awk:通过第一个字段汇总表格并合并后续的列

时间:2019-02-01 12:15:48

标签: awk

我有下表:

id1 0720f5eb2d611dc66e0e9941d516961f    193 PANTHER PTHR34107       7   187 9.50E-16    T   01.02.19                
id2 32912bc00b9b84f6b06600aff56cef8f    138 PANTHER PTHR10302:SF0       2   119 7.00E-42    T   01.02.19    IPR011344   Single-stranded DNA-binding protein GO:0003697|GO:0006260   Reactome: R-HSA-2151201
id2 32912bc00b9b84f6b06600aff56cef8f    138 PANTHER PTHR10302       2   119 7.00E-42    T   01.02.19    IPR000424   Primosome PriB/single-strand DNA-binding    GO:0003697  Reactome: R-HSA-2151201

它是由16列,并且是制表符分隔。

现在,我想通过以下方式合并此表:

  1. 通过第一列进行汇总
  2. 连接各列,以使原始表中每个id的相同字段之间用;隔开

因此,我想要的输出将是:

id2 PTHR10302:SF0; PTHR10302        2-119; 2-119    7.0E-42; 7.0E-42    T; T    IPR011344; IPR000424    Single-stranded DNA-binding protein; Primosome PriB/single-strand DNA-binding
id1     PTHR34107       7-187   9.5E-16 T

第2、3、4和10列可以省略。第7和8列由-合并。

我可以通过以下命令解决1.

awk 'BEGIN{FS=OFS="\t"}{unique[$1]=(unique[$1] FS $5 FS $6 FS $7 "-" $8 FS $9 FS $10 FS $12 FS $13); next}END{for (i in unique) print i,unique[i]}'

,其通过总结id,但不级联这些字段:

id2     PTHR10302:SF0       2-119   7.0E-42 T   IPR011344   Single-stranded DNA-binding protein PTHR10302       2-119   7.0E-42 T   IPR000424   Primosome PriB/single-strand DNA-binding
id1     PTHR34107       7-187   9.5E-16 T

但是我该怎么做2.

2 个答案:

答案 0 :(得分:0)

这并不容易,但它是可能的。

首先,您需要两个数组。一个是'ids'数组,另一个是'data'数组。

对于每一行,您应该更新'ids'数组(这样它将包含所有可能的ID):

  ids[$1] = [$1]

然后,在 '数据'阵列你应该存储的连接数据。此阵列的索引将是“fake'-多维:

  data[$1,5] = data[$1,5] ? data[$1,5] "; " $5 : $5
  data[$1,6] = data[$1,6] ? data[$1,6] "; " $6 : $6
  data[$1,78] = data[$1,78] ? data[$1,78] "; " $7 "-" $8 : $7 "-" $8
  data[$1,9] = data[$1,9] ? data[$1,9] "; " $9 : $9
  data[$1,10] = data[$1,10] ? data[$1,10] "; " $10 : $10
  data[$1,12] = data[$1,12] ? data[$1,12] "; " $12 : $12
  data[$1,13] = data[$1,13] ? data[$1,13] "; " $13 : $13

'END'块中,您应该迭代'ids'数组,但要从'data'数组中获取值:

END {
  for (i in ids)
    print i, data[i,$5], data[i,$6], data[i,$78], data[i,$9], data[i,$10], data[i,$12], data[i,$13]
}

P.S .:如果您使用 gawk 的较新版本,则可以获得更简单的方法,因为这些版本支持真正的多维数组。

答案 1 :(得分:0)

正如@tripleee所述,Perl会这样做。检查一下

$ cat rororo.txt
id1 0720f5eb2d611dc66e0e9941d516961f    193 PANTHER PTHR34107       7   187 9.50E-16    T   01.02.19
id2 32912bc00b9b84f6b06600aff56cef8f    138 PANTHER PTHR10302:SF0       2   119 7.00E-42    T   01.02.19    IPR011344   Single-stranded DNA-binding protein GO:0003697|GO:0006260   Reactome: R-HSA-2151201
id2 32912bc00b9b84f6b06600aff56cef8f    138 PANTHER PTHR10302       2   119 7.00E-42    T   01.02.19    IPR000424   Primosome PriB/single-strand DNA-binding    GO:0003697  Reactome: R-HSA-2151201

$ ./join_tab.pl rororo.txt
id2 PTHR10302:SF0;PTHR10302     2-119;2-119     7.00E-42;7.00E-42       T;T     IPR011344;IPR000424     Single-stranded DNA-binding;Primosome PriB/single-strand
id1 PTHR34107   7-187   9.50E-16        T

$

脚本:

$ cat ./join_tab.pl
perl -lane '
$id=$F[0];
$fs="$F[5]-$F[6]";
$f11="$F[11] $F[12]";
@t4 = @{$kv1{$id}}; push(@t4,$F[4]); $kv1{$id}=[@t4];
@t56 = @{$kv2{$id}}; push(@t56,$fs); $kv2{$id}=[@t56];
@t7 = @{$kv3{$id}}; push(@t7,$F[7]); $kv3{$id}=[@t7];
@t8 = @{$kv4{$id}}; push(@t8,$F[8]); $kv4{$id}=[@t8];
@t10 = @{$kv5{$id}}; push(@t10,$F[10]); $kv5{$id}=[@t10];
@t11 = @{$kv6{$id}}; push(@t11,$f11); $kv6{$id}=[@t11];
END {
while( ($x,$y) = each(%kv1))
{
 @t4=@{$kv1{$x}};  @t56=@{$kv2{$x}};
 @t7 = @{$kv3{$x}};  @t8 = @{$kv4{$x}};
 @t10 = @{$kv5{$x}};  @t11 = @{$kv6{$x}};
 print "$x ", join(";",@t4), "\t",join(";",@t56), "\t",join(";",@t7),"\t",join(";",@t8),"\t",join(";",@t10),"\t",join(";",@t11)   ;
}

} ' $1
$