AWK for循环永远没有BEGIN



在AWK中不使用BEGIN的循环在根据条件打印数字后将永远失效-

使用BEGIN,只要i的值为5,循环就结束

$ awk 'awk 'BEGIN { for (i = 1; i <= 5; ++i) print i }'
1
2
3
4
5

无BEGIN-

$ awk '{ for (i = 1; i <= 5; ++i) print i }'
-> Press enter here for output
1
2
3
4
5
-> Press enter again and printed numbers again .
1
2
3
4
5
1
2
3
4
5
^C -> control C to come out of loop

虽然我知道BEGIN块将在程序开始时执行一次,但没有开始,只要满足退出条件,命令就不应该退出吗?

请帮助了解这里发生了什么。

谢谢!

循环确实退出,但每个输入行执行一次循环,直到到达输入结束。当输入提供EOF指示时,尝试键入control-D而不是control-C。将print i更改为print NR, i,并在脚本中添加END{print "Done!"}语句,以查看发生了什么。

你问错了问题。

第二次实验中的行为是意料之中的。您没有在命令行上指定文件名,所以awk读取标准输入。它一次读取一行,直到到达文件末尾(就像从实际文件中读取一样(。并且,它执行您为每一行指定的规则;空行是无关紧要的。那么:ctrl-C是一种不文明的暴力终止程序的方式;正确的方法是发出ctrl-D,标记"文件"的结束,并允许awk正常终止。

请注意,在您的问题中,"退出循环"one_answers"程序终止"之间的混淆。当满足退出条件时,循环结束,然后awk前进到输入中的下一行。一般来说,退出作为程序规则一部分的循环与awk程序本身的终止无关。

"意外"行为发生在您的第一次实验中。在那里,awk也从标准输入读取;为什么它不等待EOF(ctrl-D(才退出,甚至认为BEGIN规则当然只执行一次?

答案是"因为这是指定的行为。"例如:https://www.gnu.org/software/gawk/manual/html_node/Using-BEGIN_002fEND.html

如果awk程序只有BEGIN规则而没有其他规则,则程序在CCD_ 14规则运行之后退出。

您可能也喜欢阅读脚注:

awk的原始版本一直读取并忽略输入,直到看到了文件的末尾。

我想说"原始版本"做了"正确的事情",但这可能让太多用户感到困惑,所以行为发生了变化。

至少,这是GNU的"指定行为";我不知道POSIX标准是怎么说的。

最新更新