计算一行中零的数量,将计数添加到新列

Counting number of zeros in a row, adding count to new column

我有一个制表符分隔的 table,看起来像这样:

chr1 100 110 + 2 3 0 8 6
chr1 150 200 + 1 4 0 2 0
chr1 200 220 + 1 4 2 0 0
chr1 250 260 + 4 2 6 1 3

我想计算第 5-9 列中有多少个零,并将该数字添加到第 10 列:

chr1 100 110 + 2 3 0 8 6 1
chr1 150 200 + 1 4 0 2 0 2
chr1 200 220 + 1 4 2 0 0 2
chr1 250 260 + 4 2 6 1 3 0

最终,目标是仅对那些不超过 4 个零的行进行子集化(至少有 2 列非零)。我知道如何用 awk 做这个子集,但我不知道如何计算这些列中的零。如果有更简单的方法只要求第 5-9 列之间至少有两列非零,那将是理想的。

此脚本计算零并将它们附加为最后一列:

awk '{
  cnt=0
  for (i=5;i<=9;i++) {
    cnt+=($i==0)
  }
  print [=10=], cnt
}' inputs.txt

请注意,如果条件为真,则 $i==0 产生 1,否则产生 0。因此,这可以作为计数器的增量。

rethab 的回答完美地回答了您添加额外列的第一个要求。这满足了您的第二个要求(仅打印少于 4 个零的行)。使用 awk(使用 GNU awk 测试),只需计算字段 5 和字段 9 之间的非零字段(变量 nz),并且仅当它大于或等于 2 时才打印:

$ cat foo.txt
chr1 100 110 + 2 3 0 8 6
chr1 150 200 + 1 4 0 2 0
chr1 250 260 + 0 0 0 1 0
chr1 200 220 + 1 4 2 0 0
chr1 250 260 + 4 2 6 1 3
$ awk '{nz=0; for(i=5;i<=9;i++) nz+=($i!=0)} nz>=2' foo.txt
chr1 100 110 + 2 3 0 8 6
chr1 150 200 + 1 4 0 2 0
chr1 200 220 + 1 4 2 0 0
chr1 250 260 + 4 2 6 1 3

您可以使用 gsub 其中 returns 每行的替换次数(这里是每个 s 字符串)然后打印数字:

awk '{s=;x=gsub(/0/,"&",s);print [=10=], x}' file
chr1 100 110 + 2 3 0 8 6 1
chr1 150 200 + 1 4 0 2 0 2
chr1 200 220 + 1 4 2 0 0 2
chr1 250 260 + 4 2 6 1 3 0