使用bash在每列中组合具有相同名称的行

时间:2018-02-06 18:48:24

标签: bash bioinformatics

我有一个类似以下的文件(但有52列和4,000行):

                   1NA2  1NB2  2RA2  2RB2
Vibrionaceae       0.22  0.25  0.36  1.02
Bacillaceae        2.0   1.76  0.55  0.23
Enterobacteriaceae 0.55  0.52  2.40  1.23
Vibrionaceae       0.22  0.25  0.36  1.02
Bacillaceae        2.0   1.76  0.55  0.23
Enterobacteriaceae 0.55  0.52  2.40  1.23

我希望它看起来像这样:

                   1NA2  1NB2  2RA2  2RB2
Vibrionaceae       0.44  0.50  0.72  2.04
Bacillaceae        4.0   3.52  1.10  0.46
Enterobacteriaceae 1.10  1.04  4.80  2.46

编辑:对不起,我不想删除剩余的行和列。每个行名称重复几次,所以我希望它只出现在每列中的总计1次。 我尝试过以下方法:

awk '{a[$1]+=$2}END{for(i in a) print i,a[i]}' file

但它只针对第一列进行,我希望它适用于所有52列。

1 个答案:

答案 0 :(得分:4)

使用 GNU awk和2D数组:

awk 'NR==1
     NR>1{
       for(i=2; i<=NF; i++){
         a[$1][i]+=$i
       }
     }
     END{
       for(i in a){
         printf("%-19s", i)
         for(j=2; j<=NF; j++){
           printf("%.2f  ", a[i][j])
         }
         print ""
       }
     }' file

或作为一个班轮:

awk 'NR==1; NR>1{for(i=2; i<=NF; i++){a[$1][i]+=$i}} END{for(i in a){printf("%-19s", i); for(j in a[i]){printf("%.2f  ", a[i][j])} print ""}}' file

输出:

                   1NA2  1NB2  2RA2  2RB2
Bacillaceae        4.00  3.52  1.10  0.46  
Vibrionaceae       0.44  0.50  0.72  2.04  
Enterobacteriaceae 1.10  1.04  4.80  2.46
  

NR是行号

     

NF是一行中的字段数