比较两个或多个文件的第二列并打印所有文件的联合

时间:2017-09-01 21:08:05

标签: linux awk sed

我有四个制表符分隔文件1.txt,2.txt,3.txt,4.txt。每个都有以下格式

89  ABI1    0.19
93  ABL1    0.15
94  ABL2    0.07
170 ACSL3   0.21    

我想比较所有文件的第二列并将union(基于第二列)打印到新文件中,如下所示:

       1.txt    2.txt   3.txt   4.txt
ABL2    0.07    0.01    0.11    0.009
AKT1    0.31    0.05    0.05    0.017
AKT2    0.33    0.05    0.01    0.004

awk怎么可能? 我试过跟随,但这只比较了第一列,

awk  'NR==FNR {h[$1] = $0; next} {print $1,h[$1]}' OFS="\t" 2.txt 1.txt   

但是当我将其更改为比较第二列时,它不起作用

awk  'NR==FNR {h[$2] = $0; next} {print $1,h[$2]}' OFS="\t" 2.txt 1.txt    

此外,这一次仅适用于两个文件。

通过比较awk中的第二列,有没有办法在四个文件上执行此操作?

1 个答案:

答案 0 :(得分:1)

排序输入文件上使用join,并假设shell使用<(...)了解进程替换(我使用了您为每个提供的数据副本输入文件,只需在顶部添加一行进行识别,这是AAA行:

$ join <( join -1 2 -2 2 -o 0,1.3,2.3 1.txt 2.txt ) \
       <( join -1 2 -2 2 -o 0,1.3,2.3 3.txt 4.txt )
AAA 1 2 3 4
ABI1 0.19 0.19 0.19 0.19
ABL1 0.15 0.15 0.15 0.15
ABL2 0.07 0.07 0.07 0.07
ACSL3 0.21 0.21 0.21 0.21

这里有三个连接。要执行的前两个是<(...)中的那些。第一个连接前两个文件,第二个连接最后两个文件。其中一个连接的结果看起来像

AAA 1 2
ABI1 0.19 0.19
ABL1 0.15 0.15
ABL2 0.07 0.07
ACSL3 0.21 0.21

选项-o 0,1.3,2.3表示“从两个文件中输出连接字段和字段3”。 -1 2 -2 2表示“将每个文件的字段2用作连接字段(而不是字段1)”。

最外面的join获取两个结果并执行产生输出的最终连接。

如果输入文件未在连接字段中排序:

$ join <( join -1 2 -2 2 -o 0,1.3,2.3 <(sort -k2,2 1.txt) <(sort -k2,2 2.txt) ) \
       <( join -1 2 -2 2 -o 0,1.3,2.3 <(sort -k2,2 3.txt) <(sort -k2,2 4.txt) )