如何防止从 awk **脚本**(而不是从 cli)打印到标准输出

如何防止从 awk **脚本**(而不是从 cli)打印到标准输出

[Archlinux 上的 GNU awk v4.2.1]

抑制awk从 cli 到 stdout 的默认打印操作很简单,并且在 UL 上有详细记录,例如这里。从脚本中执行此操作让我很头疼。这是玩具脚本:

#!/usr/bin/awk -f
BEGIN {FS=","} 
FNR > 1          # skip header
{   
    if ( $1 == $2 ) {
        if ( NR == 4 ) {
            printf("*** Print NR=4 ok. \n")
        } else {
            print > "/dev/null"  # print nothing
        }
    } else {
        printf("=== Fields 1 and 2 not equal (NR=%s). \n",NR)
    }
}

和玩具数据:

col1 col2
1,3
2,2
aa,aa
3.01,-353.01
4.1,4.1
101,101
hello, hello
asd,koi0

以及预期/期望的输出:

=== Fields 1 and 2 not equal (NR=2). 
*** Print NR=4 ok. 
=== Fields 1 and 2 not equal (NR=5).
=== Fields 1 and 2 not equal (NR=8).
=== Fields 1 and 2 not equal (NR=9).

相反,我得到:

=== Fields 1 and 2 not equal (NR=1). 
1,3
=== Fields 1 and 2 not equal (NR=2). 
2,2
aa,aa
*** Print NR=4 ok. 
3.01,-353.01
=== Fields 1 and 2 not equal (NR=5). 
4.1,4.1
101,101
hello, hello
=== Fields 1 and 2 not equal (NR=8). 
asd,koi0
=== Fields 1 and 2 not equal (NR=9). 

为了抑制输出到标准输出,我尝试使用: getline{}nextprintf("")甚至使用奇怪的ORS=""; print ""; ORS="\n"而不是print > "/dev/null"。显然我在那个该死的脚本中做了一些非常错误的事情,并且找不到什么......

答案1

仅有的错误是

FNR > 1          # skip header
{ 

应该是

FNR > 1 {        # skip header

带有条件的代码块必须与条件在同一行开始。

你原来的剧本是什么实际上做是第一

FNR > 1

这将打印从第二行开始的所有行(当条件没有关联的代码块时,默认操作是在条件为 true 时打印当前记录,就像该块已为 true 一样{ print })。

然后它将后面的块应用到每个行(因为该块没有关联的条件)。

这不是 GNU 的特性awk。所有的awk实现都应该像这样。


至于脚本的其他部分:

    } else {
        print > "/dev/null"  # print nothing
    }

这可以删除,留下

#!/usr/bin/awk -f

BEGIN { FS = "," } 

FNR > 1 {   
    if ( $1 == $2 ) {
        if ( NR == 4 )
            printf("*** Print NR=4 ok.\n")
    } else
        printf("=== Fields 1 and 2 not equal (NR=%s).\n", NR)
}

或者,

#!/usr/bin/awk -f

BEGIN { FS = "," } 

FNR == 1 { next }

$1 == $2 && NR == 4 { printf("*** Print NR=4 ok.\n") }
$1 != $2            { printf("=== Fields 1 and 2 not equal (NR=%s).\n", NR) }

相关内容