awk 中 NF 减少后

post-decrement of NF in awk

提问人:William Pursell 提问时间:2/12/2021 最后编辑:Ed MortonWilliam Pursell 更新时间:2/12/2021 访问量:142

问:

我对以下内容有点困惑:

$ echo foo bar baz | awk '{printf "%d:", NF--; print NF}'
3:2
$ echo foo bar baz | awk '{printf "%d:", NF; $NF=""; NF -= 1; print NF}' 
3:2
$ echo foo bar baz | awk '{printf "%d:", NF; $(NF--)=""; print NF}' 
3:3

我在 (macos) 和 .为什么第3种情况下NF的后减少不适用?这种行为是预期的、由标准强制执行的,还是实现的怪癖?awk version 20070501GNU Awk 4.0.2


埃德·莫顿(Ed Morton)编辑:FWIW 我发现以下是一个更令人信服的例子:

$ echo foo bar baz | awk '{printf "%d:", NF; NF--; $NF=""; print NF}'
3:2

$ echo foo bar baz | awk '{printf "%d:", NF; --NF; $NF=""; print NF}'
3:2

$ echo foo bar baz | awk '{printf "%d:", NF; $NF=""; NF--; print NF}'
3:2

$ echo foo bar baz | awk '{printf "%d:", NF; $NF=""; --NF; print NF}'
3:2

$ echo foo bar baz | awk '{printf "%d:", NF; $(--NF)=""; print NF}'
3:2

$ echo foo bar baz | awk '{printf "%d:", NF; $(NF--)=""; print NF}'
3:3

问题是为什么最后一个示例(赋值后递减)的行为与所有其他情况不同,无论您认为它应该等同于哪一种情况。

评论

1赞 anubhava 2/12/2021
例如: 将输出echo 'foo bar baz' | awk '{printf "%d:", NF; $(--NF)=""; print NF}'3:2

答:

7赞 Barmar 2/12/2021 #1

递减后的值是变量递减前的值。因此,最后一种情况是在递减后添加一个新字段,这会更新 。NFNF

$(NF--) = "";

相当于

temp = NF;  # temp == 3
NF--;       # NF == 2
$temp = ""; # adds a new field 3, so now NF == 3

评论

0赞 Barmar 2/12/2021
没错,但鉴于它在此实现中起作用,这就是它正在做的事情。
1赞 Ed Morton 2/12/2021
是的,看起来这就是正在发生的事情。当然,我们可以通过对类似功能使用后增量来测试它 - 该行为由 POSIX 指定,因此它会从等式中删除“未定义的行为”。@AndyLester我删除了该评论,因为我认为它实际上与此无关,毕竟,我太快将其视为“不要那样做”(尽管我仍然认为这是最好的建议!