添加字段编号

时间:2019-04-26 22:10:53

标签: awk

我有一个包含多行和两或四列的文本文件。如果两列,则第一列为id,第二列为数字,如果四列第一和第二列为id,第三列和第四列为数字。对于四列行,第二和第四列单元格可以有多个条目,并用逗号分隔。如果只有两栏,我想按原样打印;但是如果有四列,我只想打印第一列ID,在第二列中,我想要该行的第三列和第四列中存在的所有数字的总和。

输入

    CG  AT,AA,CA    17  1,1,1
    GT  14
    TB  AC,TC,TA,GG,TT,AR,NN,NM,AB,AT,TT,TC,CA,BB,GT,AT,XT,MT,NA,TT         552 6,1,1,2,2,1,2,1,5,3,4,1,2,1,1,1,3,4,5,4
    TT  CG,GT,TA,GB 105 3,4,1,3

预期产量

    CG  20
    GT  14
    TB  602
    TT  116

2 个答案:

答案 0 :(得分:3)

如果实际文件中没有前导空格,请使用$1而不是$2

$ awk -F '[ ,]+' '{for(i=1; i<=NF; i++) s+=$i; print $2, s; s=0}' <<EOF
    CG  AT,AA,CA    17  1,1,1
    GT  14
    TB  AC,TC,TA,GG,TT,AR,NN,NM,AB,AT,TT,TC,CA,BB,GT,AT,XT,MT,NA,TT         552 6,1,1,2,2,1,2,1,5,3,4,1,2,1,1,1,3,4,5,4
    TT  CG,GT,TA,GB 105 3,4,1,3
EOF

CG 20
GT 14
TB 602
TT 116
  • -F '[ ,]+'表示“字段由一个或多个空格或逗号分隔”。

  • 没有与{action}关联的条件,因此将在每一行上执行。

  • NF是字段数,而$X是第X个字段。

  • 字符串等于0,因此我们可以简单地将每个字段加在一起以获得总和。

  • 在打印第一个非空白字段和​​总和之后,我们将下一行的总和重置。

答案 1 :(得分:1)

这是一个编码为尽可能接近您的说明的解决方案(没有用于拆分字段的技巧,因此很容易推理):

awk '
    NF == 2 {
        print $1, $2
        next
    }
    NF == 4 {
        N = split($4, f, /,/)
        for (i = 1; i <= N; ++i)
            $3 += f[i]
        print $1, $3
    }'

我注意到您的输入部分包含前导空格。如果前导空格确实存在(并且不相关),我们可以在脚本中添加前导{ sub(/^ +/, "") }