Bash 如何将n个tab分隔的文件按唯一的前3列和平均的第4列合并?

Bash 如何将n个tab分隔的文件按唯一的前3列和平均的第4列合并?,bash,Bash,我一直在寻找一种更简单的合并和平均n(n的方法,因为您加入的列总是相同的。您可以使用paste而不是joinpaste一次加入两个以上的文件 paste table1 table2 ... tableN | awk '{ print $1,$2,$3,($4+$8+...+$N*4)/N }' 这仍然需要手动调整awk命令。您可以使用awk中的循环来解决此问题 paste table1 table2 ... | awk '{ avg=0; for (i=4; i<=NF; i+=4) a

我一直在寻找一种更简单的合并和平均n(n的方法,因为您加入的列总是相同的。您可以使用
paste
而不是
join
paste
一次加入两个以上的文件

paste table1 table2 ... tableN | awk '{ print $1,$2,$3,($4+$8+...+$N*4)/N }'
这仍然需要手动调整
awk
命令。您可以使用
awk
中的循环来解决此问题

paste table1 table2 ... |
awk '{ avg=0; for (i=4; i<=NF; i+=4) avg+=$i; print $1,$2,$3,avg*4/NF }'
粘贴表1表2|

awk'{avg=0;for(i=4;i因为您加入的列总是相同的,所以您可以使用
paste
而不是
join
paste
一次加入两个以上的文件

paste table1 table2 ... tableN | awk '{ print $1,$2,$3,($4+$8+...+$N*4)/N }'
这仍然需要手动调整
awk
命令。您可以使用
awk
中的循环来解决此问题

paste table1 table2 ... |
awk '{ avg=0; for (i=4; i<=NF; i+=4) avg+=$i; print $1,$2,$3,avg*4/NF }'
粘贴表1表2|

awk'{avg=0;for(i=4;i使用
gnu-awk
的单个命令可能适用于您:

awk 'BEGIN{FS=OFS="\t"} FNR == NR{
   a[$1] = 1
   for (i=2; i<=NF; i++)
      s[$1][i] = $i
   next
}
a[$1] {
   for (i=2; i<=NF; i++)
      s[$1][i] += $i
}
END {
   for (i in a) {
      r = i
      for (j=2; j<=NF; j++)
         r = sprintf("%s%s" (j == NF ? "%.2e" : "%d"), r, OFS, s[i][j]/(ARGC-1))
      print r
   }
}' tableN*

使用
gnu awk
的单个命令可能适用于您:

awk 'BEGIN{FS=OFS="\t"} FNR == NR{
   a[$1] = 1
   for (i=2; i<=NF; i++)
      s[$1][i] = $i
   next
}
a[$1] {
   for (i=2; i<=NF; i++)
      s[$1][i] += $i
}
END {
   for (i in a) {
      r = i
      for (j=2; j<=NF; j++)
         r = sprintf("%s%s" (j == NF ? "%.2e" : "%d"), r, OFS, s[i][j]/(ARGC-1))
      print r
   }
}' tableN*

只有一点小小的改进:您可以使用
cut-f1-N
而不是
awk'{print$1…$N}'
。在您的示例中,第一列似乎总是相同的。是这样还是有一些文件的行数比其他文件少/不同?谢谢您的回答。是的,所有表的行数和顺序都相同(基于前三列)。只有一个小的改进:而不是
awk'{print$1…$N}“
您可以使用
cut-f1-N
。在您的示例中,第一列似乎总是相同的。是这样的,还是有一些文件的行数比其他文件少/不同?谢谢您的回答。是的,所有表的行数和顺序都相同(基于前三列)谢谢你的回复。那么平均值是:awk-vn=$N'{avg=0;for(i=4;i@gdeniz哎呀,忘了除法了。您的解决方案似乎还可以。但是,由于所有文件都有4列,您不需要
-v N=…
部分。只需使用
(NF/4)
而不是
N
,请参见编辑。不幸的是,我不能推荐任何阅读资料。我通过查看stackoverflow上的示例学习了
awk
。感谢您的回复。平均值为:awk-v N=$N'{avg=0;例如(i=4;i@gdeniz哎呀,忘了除法了。您的解决方案似乎还可以。但是,由于所有文件都有4列,所以您不需要
-v N=…
部分。只需使用
(NF/4)
而不是
N
,请参见编辑。不幸的是,我无法推荐任何阅读资料。我通过查看这里有关stackoverflow的示例学习了
awk