如何基于列合并两个文件作为键

时间:2014-11-21 05:27:33

标签: bash shell awk sed

如何基于列合并两个文件作为键,匹配a.txt中的$ 1列并附加基于$ 3列的b.txt

a.txt
aa; 2.5; 0.001;
ab; 1.5; 0.003;
ac; 0.4; 0.002;

b.txt

20-Nov-2014; 1775.00; aa;
20-Nov-2014; 1775.00; aa;
20-Nov-2014; 1463.40; ab;
20-Nov-2014; 1463.40; ac;
20-Nov-2014; 1463.40; ab;

Desired output look like this 
20-Nov-2014; 1775.00; aa; aa; 2.5; 0.001;
20-Nov-2014; 1775.00; aa; aa; 2.5; 0.001;
20-Nov-2014; 1463.40; ab; ab; 1.5; 0.003;
20-Nov-2014; 1463.40; ac; ac; 0.4; 0.002;
20-Nov-2014; 1463.40; ab; ab; 1.5; 0.003;

Thanks

3 个答案:

答案 0 :(得分:1)

$ awk -F';' 'FNR==NR{a[$1]=$0;next;} {print $0" " a[substr($3,2)];}' a.txt b.txt
20-Nov-2014; 1775.00; aa; aa; 2.5; 0.001;
20-Nov-2014; 1775.00; aa; aa; 2.5; 0.001;
20-Nov-2014; 1463.40; ab; ab; 1.5; 0.003;
20-Nov-2014; 1463.40; ac; ac; 0.4; 0.002;
20-Nov-2014; 1463.40; ab; ab; 1.5; 0.003;

如何运作

awk隐式循环遍历文件中的每一行。每一行都分为几个字段。

  • -F';'

    这告诉awk使用分号作为字段分隔符。

  • FNR==NR{a[$1]=$0;next;}

    NR是到目前为止已读取的行数,FNR是到目前为止从当前文件中读取的行数。因此,在FNR==NR时,我们仍在阅读第一个文件a.txt。在这种情况下,此集会将刚刚读入的整行($0)分配给键a下的数组$1,即第三个字段。

    next告诉awk跳过下面的其他命令并跳转到下一行并重新开始。

  • print $0" " a[substr($3,2)]

    如果我们到达这里,那意味着我们正在处理第二个文件b.txt。在这种情况下,打印此文件的每一行,后跟数组a中的行,其中键与第三个字段匹配。

    在文件b.txt中,第三个字段以空格开头。在数组a中查找此字段时,会使用substr函数删除该空格。

答案 1 :(得分:1)

awk -F\; 'NR==FNR{arr[" "$1]=$0;next} {print $0, arr[$3]}'  a b
20-Nov-2014; 1775.00; aa; aa; 2.5; 0.001;
20-Nov-2014; 1775.00; aa; aa; 2.5; 0.001;
20-Nov-2014; 1463.40; ab; ab; 1.5; 0.003;
20-Nov-2014; 1463.40; ac; ac; 0.4; 0.002;
20-Nov-2014; 1463.40; ab; ab; 1.5; 0.003;

答案 2 :(得分:0)

$ awk -F'; ?' 'NR==FNR{a[$1]=$0;next} {print $0, a[$3]}' a.txt b.txt
20-Nov-2014; 1775.00; aa; aa; 2.5; 0.001;
20-Nov-2014; 1775.00; aa; aa; 2.5; 0.001;
20-Nov-2014; 1463.40; ab; ab; 1.5; 0.003;
20-Nov-2014; 1463.40; ac; ac; 0.4; 0.002;
20-Nov-2014; 1463.40; ab; ab; 1.5; 0.003;