用于隔离行的 awk for 循环语法

awk for-loop syntax for isolating rows

我有一个如下所示的输入文件:

1   Gene1   0.4     0.0009
2   Gene2   0.0003  0.00004
3   Gene3   0.04    0.9
4   Gene4   0.0009  0.00002
5   Gene5   0.8     0.00003

并且我希望隔离第三个($3)和第四个($4)字段小于或等于 0.01 的行,

我用过:

awk -F"\t" '{ if (<=0.01 && <=0.01) print [=11=] }' input

它工作正常,但我想使用 awk for 循环来执行此操作,因为我的实际文件包含十五个这样的字段,我不想在上面的代码中键入每个字段。

我试过了:

awk -F"\t" '{ for (i=3; i<=NF; i++) if (i<=0.01) print [=12=] }' input

但是没用。我不擅长 awk for 循环语法,所以任何帮助将不胜感激。

谢谢。

字段 i 的值为 $i。因此,替换:

awk -F"\t" '{ for (i=3; i<=NF; i++) if (i<=0.01) print [=10=] }' input

有:

awk -F"\t" '{ for (i=3; i<=NF; i++) if ($i<=0.01) print [=11=] }' input

然而,以上将打印同一行的多个副本。如果你不想这样:

$ awk '{f=0; for (i=3; i<=NF; i++) if ($i<=0.01)f=1;} f' input
1   Gene1   0.4     0.0009
2   Gene2   0.0003  0.00004
4   Gene4   0.0009  0.00002
5   Gene5   0.8     0.00003

上面命令中最后的 fawk shorthand 如果 f 不为零则打印该行。

以上适用or逻辑。您的原始代码使用 and 逻辑。要使用 and 逻辑并仅在所有列的值都小于或等于 0.01 时打印,请尝试:

$ awk '{f=1; for (i=3; i<=NF; i++) if ($i>0.01)f=0;} f' input
2   Gene2   0.0003  0.00004
4   Gene4   0.0009  0.00002

或者,这也是一样的,但只使用 <= 测试:

$ awk '{f=1; for (i=3; i<=NF; i++) f = f && ($i<=0.01);} f' input
2   Gene2   0.0003  0.00004
4   Gene4   0.0009  0.00002

如果所有字段都具有给定值或其中一个字段具有给定值或某些其他组合,则不清楚是否要打印该行,但类似这样的方法可以以任何一种方式工作:

awk '
{
    cnt = 0
    for (i=3; i<=NF; i++) {
        cnt += (($i)+0 <= 0.01 ? 1 : 0)
    }
}
cnt { print "at least one true:", [=10=] }
cnt == (NF-3) { print "all true:", [=10=] }
' file

我添加了 +0 来强制进行数值比较,为了清楚起见,我将其设为三元表达式,而不是简单地使用比较结果。