我有四个制表符分隔文件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中的第二列,有没有办法在四个文件上执行此操作?
答案 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) )