【问题标题】:compare 2nd column of two or more files and print union of all files比较两个或多个文件的第二列并打印所有文件的并集
【发布时间】:2017-09-02 05:40:51
【问题描述】:

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

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

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

       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 中的第二列来处理四个文件?

【问题讨论】:

  • 你能把2.txt3.txt的内容贴出来吗?

标签: linux awk sed


【解决方案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

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

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) )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-18
    • 1970-01-01
    • 2020-12-13
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多