我有一个带有数字的文件,我想要对两行中的数字进行求和,然后在我的最后一步中,我想过滤出数量大于或等于3的“0”的行数总数。我写了一个小例子来说清楚:
这是我的文件(没有c的注释),它包含2对线(= 4行)和5列。
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
谢谢!
答案 0 :(得分:2)
另一种变体可能有助于避免某些输入情况下的循环迭代:
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
答案 1 :(得分:1)
好吧,经过多挖一点后,我发现打印上一行非常简单(我让自己变得复杂)
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
中,并在条件有利时打印。
希望它也可以帮助其他人
答案 2 :(得分:1)
$ 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