根据第一列的开头在txt中合并几行

时间:2019-07-18 16:40:14

标签: linux bash perl awk sed

我有一个txt文件1,其中有四列:

Staphylococcus_aureus<0.8 1 0 3
Staphylococcus_aureus_subsp_aureus<0.8 1 2 0
Staphylococcus_aureus_subsp_aureus_S228<0.8 2 0 2

我要生成一个输出txt file2,如下所示:

Staphylococcus_aureus<0.8 4 2 5

说明:第一列以相同的开头“ Staphylococcuscus_aureus <0.8”,我想添加第二,第三,第四列。

我在想awk,sed,perl或python。

有什么想法吗?

5 个答案:

答案 0 :(得分:1)

要输出第2-4列的总和,可以使用awk:

awk '{ col2+=$2; col3+=$3; col4+=$4 } END { printf "%d %d %d\n", col2, col3, col4 }' file1 > file2

更新您的文章以解释在输出中生成第1列的逻辑,我们将看到如何将这一部分最好地纳入答案。

答案 1 :(得分:1)

一笔一笔

$ awk 'NR==1          {f1=$1; split($1,ks,"<"); k=ks[1]} 
       index($1,k)==1 {f2+=$2; f3+=$3; f4+=$4} 
       END            {print f1,f2,f3,f4}' file

Staphylococcus_aureus<0.8 4 2 5

从第一行抓取密钥,添加字段,最后打印结果。

答案 2 :(得分:0)

重击解决方案:

tac file1 | while read c1 c2 c3 c4; do echo $c1 $((A+=c2)) $((B+=c3)) $((C+=c4)) > file2; done

答案 3 :(得分:0)

这可能对您有用(GNU sed和bash):

sed -E ':a;N;/^([^<]+)<(\S+) (\S+) (\S+) (\S+)\n\1\S+\2 (\S+) (\S+) (\S+)$/s//printf "%s<%s %s %s %s" \1 \2 $((\3+\6)) $((\4+\7)) $((\5+\8))/e;$!ta;P;D' file

使用模式匹配和向后引用以使用公共密钥累积每行的最后3个字段。

在替换命令上使用e标志用printf命令替换模式空间,该命令在求值时会动态更新累积值。

答案 4 :(得分:-1)

Perl解决方案:

$ perl -ne '@c=split; $k=$c[0] if $.==1; $c1+=$c[1]; $c2+=$c[2]; $c3+=$c[3]; }{ print "$k $c1 $c2 $c3\n"' file1
Staphylococcus_aureus<0.8 4 2 5

$k键只是从第一行的第一列(在$.==1时)

否则,这是awk解决方案,列索引从零开始

对于从$ k的某个部分开始的行,可以有条件地递增变量的增量...但是如前所述,尚不清楚您要在其中做什么。