如何使用多列连接(合并)多个文件(按行)

时间:2018-04-23 07:56:37

标签: bash awk merge

我有多个文件,内容如下:

==> file1.tab <==
Contig  Position    TS-568_ALLELE   TS-568_FREQUENCY    TS-568_COVERAGE
ch00    11009393    A/C 0.02/0.97   93
ch00    11009395    A/C/T   0.01/0.97/0.01  96
ch00    11009416    A/G/T   0.12/0.83/0.04  97
ch00    11009421    A/G 0.17/0.82   97
ch00    11009427    A/C/T   0.02/0.96/0.00  101
ch01    11009436    C/T 0.99/0.00   103
ch01    11009437    G/T 0.00/0.99   104
ch02    11009441    A/G 0.07/0.92   101
ch02    11009445    G   1.0 96

==> file2.tab <==
Contig  Position    TS-602_ALLELE   TS-602_FREQUENCY    TS-602_COVERAGE
ch00    11009393    C   1.0 7
ch00    11009395    C   1.0 7
ch00    11009416    G   1.0 5
ch00    11009421    G   1.0 5
ch00    11009427    C   1.0 4
ch01    11009436    C   1.0 4
ch01    11009437    T   1.0 4
ch02    11009441    G   1.0 5
ch02    11009445    G   1.0 5

==> file3.tab <==
Contig  Position    TS-586_ALLELE   TS-586_FREQUENCY    TS-586_COVERAGE
ch00    11009393    C   1.0 34
ch00    11009395    C   1.0 35
ch00    11009416    A/G/T   0.07/0.89/0.02  39
ch00    11009421    A/G 0.10/0.89   39
ch00    11009427    A/C 0.02/0.97   37
ch01    11009436    C   1.0 44
ch01    11009437    T   1.0 44
ch02    11009441    A/G 0.06/0.93   45
ch02    11009445    G   1.0 44

我读到关于bash的加入,但我的问题是我需要基于两个第一列而不是单个列加入它们(ch00 11009427是唯一标识符,ch01 11009427或ch03 11009427也可以在列表)。

因此,预期的输出将是:

==> file_all.tab <==
Contig  Position    TS-568_ALLELE   TS-568_FREQUENCY    TS-568_COVERAGE TS-602_ALLELE   TS-602_FREQUENCY    TS-602_COVERAGE TS-586_ALLELE   TS-586_FREQUENCY    TS-586_COVERAGE
ch00    11009393    A/C 0.02/0.97   93  C   1.0 7   C   1.0 34
ch00    11009395    A/C/T   0.01/0.97/0.01  96  C   1.0 7   C   1.0 35
ch00    11009416    A/G/T   0.12/0.83/0.04  97  G   1.0 5   A/G/T   0.07/0.89/0.02  39
ch00    11009421    A/G 0.17/0.82   97  G   1.0 5   A/G 0.10/0.89   39
ch00    11009427    A/C/T   0.02/0.96/0.00  101 C   1.0 4   A/C 0.02/0.97   37
ch01    11009436    C/T 0.99/0.00   103 C   1.0 4   C   1.0 44
ch01    11009437    G/T 0.00/0.99   104 T   1.0 4   T   1.0 44
ch02    11009441    A/G 0.07/0.92   101 G   1.0 5   A/G 0.06/0.93   45
ch02    11009445    G   1.0 96  G   1.0 5   G   1.0 44

文件根据第1列和第2列进行排序,行数相等。这些文件中大约有150个,总大小为6.5 GB

1 个答案:

答案 0 :(得分:1)

awk可以达到你想要的效果。

awk -v OFS='\t' 'BEGIN{PROCINFO["sorted_in"]="@ind_str_asc"} {for(i=3;i<=NF;i++) a[$1 OFS $2]=a[$1 OFS $2] OFS $i}END{for(i in a)print i,a[i]}'

简要说明,

  • OFS='\t':将输出字段分隔符设置为\t
  • PROCINFO["sorted_in"]="@ind_str_asc":按索引按升序排序数组作为字符串。有关详细信息,请参阅here
  • for(i=3;i<=NF;i++) a[$1 OFS $2]=a[$1 OFS $2] OFS $i:将值保存到数组中的特定indice。
  • END{for(i in a)print i,a[i]}:在数组中打印indice及其对应的值。