Unix连接在Windows 7上产生不一致的结果

时间:2013-12-28 13:27:30

标签: unix join sed awk

拥有一个数据集,其中一个文件中的最大记录数为~130,000。

这是第一个文件的子集,1.txt:

CID|UID|Key|sis_URL
1|D000108|RDHQFKQIGNGIED|http://sis.gov/regno=0000870779
1|D000108|RDHQFKQIGNGIED|http://sis.gov/regno=0014992622
1|D000644|RDHQFKQIGNGIED|http://sis.gov/regno=0000870779
1|D000644|RDHQFKQIGNGIED|http://sis.gov/regno=0014992622
1|D002331|RDHQFKQIGNGIED|http://sis.gov/regno=0000870779
1|D002331|RDHQFKQIGNGIED|http://sis.gov/regno=0014992622
11|C024565|WSLDOOZREJYCGB|http://sis.gov/regno=0000107062
13|C009947|PBKONEOXTCPAFI|http://sis.gov/regno=0000120821
13|C009947|PBKONEOXTCPAFI|http://sis.gov/regno=0063697187

这是第二个文件的子集,2.txt:

CID|bro_URL
11|http://bro.gov/nmbr=0149
13|http://bro.gov/nmbr=0119

我在Windows 7下运行gnuwin32,64位内存为8GB;因此需要为windows使用双引号。 join命令是:

join -t"|" -1 1 -2 1 -a1 -a2 -e "NULL" -o "0,1.2,1.3,1.4,2.2" 1.txt 2.txt > 3_.txt

这是输出文件3.txt。

CID|UID|Key|sis_URL|bro_URL
1|D000108|RDHQFKQIGNGIED|http://sis.gov/regno=0000870779|NULL
1|D000108|RDHQFKQIGNGIED|http://sis.gov/regno=0014992622|NULL
1|D000644|RDHQFKQIGNGIED|http://sis.gov/regno=0000870779|NULL
1|D000644|RDHQFKQIGNGIED|http://sis.gov/regno=0014992622|NULL
1|D002331|RDHQFKQIGNGIED|http://sis.gov/regno=0000870779|NULL
1|D002331|RDHQFKQIGNGIED|http://sis.gov/regno=0014992622|NULL
11|NULL|NULL|NULL|http://bro.gov/nmbr=0149
13|NULL|NULL|NULL|http://bro.gov/nmbr=0119
11|C024565|WSLDOOZREJYCGB|http://sis.gov/regno=0000107062|NULL
13|C009947|PBKONEOXTCPAFI|http://sis.gov/regno=0000120821|NULL
13|C009947|PBKONEOXTCPAFI|http://sis.gov/regno=0063697187|NULL

对于CID:11和CID:13,我期待:

11|C024565|WSLDOOZREJYCGB|http://sis.gov/regno=0000107062|http://bro.gov/nmbr=0149
13|C009947|PBKONEOXTCPAFI|http://sis.gov/regno=0000120821|http://bro.gov/nmbr=0119
13|C009947|PBKONEOXTCPAFI|http://sis.gov/regno=0063697187|http://bro.gov/nmbr=0119

为什么CID:11和CID:13上的join会失败?

注意:在发布此问题之前,我运行了上面的子集并生成了正确的结果。当我运行完整集时,我得到了不正确的结果(此处显示的子集)。

知道为什么吗?任何推荐的替代方案?

当我完成join过程后,我的决赛桌将为15列宽。但是我已经在第4栏受到了阻碍。

任何提议的解决方法,例如awk

1 个答案:

答案 0 :(得分:3)

您可以尝试以下命令:

awk -f a.awk 2.txt 1.txt > 3.txt

其中a.awk是:

BEGIN { FS=OFS="|" }
NR==FNR{
    a[$1]=$2
    next
}
{
    if ($1 in a)
        $(NF+1)=a[$1]
    else 
        $(NF+1)="NULL"
    print
}

带输出:

CID|UID|Key|sis_URL|bro_URL
1|D000108|RDHQFKQIGNGIED|http://sis.gov/regno=0000870779
1|D000108|RDHQFKQIGNGIED|http://sis.gov/regno=0014992622
1|D000644|RDHQFKQIGNGIED|http://sis.gov/regno=0000870779
1|D000644|RDHQFKQIGNGIED|http://sis.gov/regno=0014992622
1|D002331|RDHQFKQIGNGIED|http://sis.gov/regno=0000870779
1|D002331|RDHQFKQIGNGIED|http://sis.gov/regno=0014992622
11|C024565|WSLDOOZREJYCGB|http://sis.gov/regno=0000107062|http://bro.gov/nmbr=0149
13|C009947|PBKONEOXTCPAFI|http://sis.gov/regno=0000120821|http://bro.gov/nmbr=0119
13|C009947|PBKONEOXTCPAFI|http://sis.gov/regno=0063697187|http://bro.gov/nmbr=0119

<强>解释

  • 我们将2.txt中的数据读入关联数组a
  • 测试NR==FNR仅用于匹配命令行中的第一个文件,即文件2.txt
  • next语句非常重要,因此2.txt不会执行下一条规则
  • 第二条规则(包含if测试的规则)仅针对1.txt执行,但来自2.txt的信息仍可通过数组a
  • 如果第一个字段与2.txt中第一列中的字段匹配,即:if ($1 in a),那么我们会在该行的末尾插入该值(NF是数字从1.txt
  • 读取的字段(即:列)
  • 如果没有匹配项,我们会插入字符串"NULL"