AWK END 行为是否将最后一行加载到手册页中的 $0 中?

mbi*_*ras 4 awk

我阅读了另一个描述如何使用AWK查看最后一行输出的答案

$ seq 42 | awk 'END { print }'
42
Run Code Online (Sandbox Code Playgroud)

因此,当END块运行时,最后一行似乎加载到$0.

这让我感到惊讶,因为第一行没有加载到BEGIN块中:

$ seq 42 | awk 'BEGIN { print }'
#=> blank
Run Code Online (Sandbox Code Playgroud)
  • 这个行为文档在任何地方吗?(我搜索了手册页,但没有找到任何内容)

Ste*_*itt 9

BEGIN块在处理任何输入之前运行,因此$0尚未初始化。

END块对 不做任何事情$0,它保留了它的最后一个值。在您的 AWK 脚本中,这只是读取的最后一行,因为 AWK 逐行读取其所有输入,执行其通常的字段拆分处理(分配$0等),但从未找到匹配的块;但例如

seq 42 | awk '{ $0 = "21" } END { print }'
Run Code Online (Sandbox Code Playgroud)

输出 21,而不是 42,所以不是“当END块运行时最后一行被加载$0”的情况。

这没有记录在gawk(1)联机帮助页中,但记录在mawk(1)(显然是对于 AWK 的实现):

类似地,在进入END操作时$0,字段 和NF的值与最后一条记录保持不变。

GNU AWK 手册确实提到了这种行为

实际上,所有 BWK awkmawk和 都gawk保留了$0for 在END规则中使用的值。

“BWK awk”是Brian Kernighan 的awk“真正的awk;它在 2005 年实现了这种行为,如其文件中所述FIXES

2005 年 4 月 24 日:进行了修改,lib.c以便将$0et al 的值保留在 END 块中,这显然是 posix 所要求的。感谢 havard eidnes 的报告和代码。

这种变化在“一个真实awk”的历史中是可见的。最新版本的 BWKawk与 GNU AWK 的行为方式相同:

$ echo three fields here | ./awk '{ $0 = "one" } END { print $0 " " NF }'
one 1
$ echo three fields here | ./awk 'END { $0 = "one"; print $0 " " NF }'
one 1
Run Code Online (Sandbox Code Playgroud)