【问题标题】:awk command to sum pairs of lines and filter out under particular conditionawk 命令对行求和并在特定条件下过滤掉
【发布时间】:2017-07-17 13:16:49
【问题描述】:

我有一个包含数字的文件,我想对两行中的数字求和,然后为每一列求和,然后在最后一步中,我想过滤掉计数大于或等于 3 的“0”的行对总和很重要。我写了一个小例子来说明清楚:

这是我的文件(没有 cmets ofc),它包含 5 列的 2 对行(=4 行)。

2 6 0 8 9  # pair 1.A
0 1 0 5 1  # pair 1.B
0 2 0 3 0  # pair 2.A
0 0 0 0 0  # pair 2.B

我需要总结成对的线,所以我得到了这样的东西(中间步骤)

2 7 0 13 10 # sum pair 1, it has one 0 
0 2 0 3 0   # sum pair 2, it has three 0 

然后我想打印原始行,但只打印那些 0(两行之和)之和小于 3 的行,因此我应该打印这个:

2 6 0 8 9  # pair 1.A
0 1 0 5 1  # pair 1.B

因为第二对行之和有三个0,所以应该排除

所以我需要从第一个文件中获取最后一个输出。

到目前为止,我能够做的是对行求和,计数零,并识别计数低于 0 的 3 的行,但我不知道如何打印导致SUM,我只能打印两行之一(最后一行)。这是我正在使用的 awk:

  awk '
  NR%2 { split($0, a); next } 
  { for (i=1; i<=NF; i++) if (a[i]+$i == 0) SUM +=1; 
  if (SUM < 3) print $0; SUM=0 }' myfile 

(这就是我现在得到的)

0 1 0 5 1 # pair 1.B

谢谢!

【问题讨论】:

    标签: bash awk


    【解决方案1】:

    另一种变体,可能有助于在某些输入情况下避免循环迭代:

    awk '!(NR%2){ zeros=0; for(i=1;i<=NF;i++) { if(a[i]+$i==0) zeros++; if(zeros>=3) next } 
         print prev ORS $0 }{ split($0,a); prev=$0 }' file
    

    输出:

    2 6 0 8 9
    0 1 0 5 1
    

    【讨论】:

      【解决方案2】:

      好吧,再挖掘一点后,我发现打印上一行相当简单(我在复杂化自己)

        awk '
        NR%2 { split($0, a) ; b=$0; next } 
        { for (i=1; i<=NF; i++) if (a[i]+$i == 0) SUM +=1; 
        if (SUM < 3) print b"\n"$0; SUM=0}' myfile
      

      所以我只需将第一行保存在变量b 中,并在条件合适时打印。 希望它也可以帮助其他人

      【讨论】:

        【解决方案3】:
        $ cat tst.awk
        !(NR%2) {
            split(prev,p)
            zeroCnt = 0
            for (i=1; i<=NF; i++) {
                zeroCnt += (($i + p[i]) == 0 ? 1 : 0)
            }
            if (zeroCnt < 3) {
                print prev ORS $0
            }
        }
        { prev = $0 }
        
        $ awk -f tst.awk file
        2 6 0 8 9
        0 1 0 5 1
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-09-20
          • 1970-01-01
          • 2020-07-07
          • 2017-11-10
          • 2022-06-25
          • 2012-12-05
          • 2017-10-04
          • 1970-01-01
          相关资源
          最近更新 更多