【问题标题】:AWK for loop goes forever without BEGINAWK for 循环在没有 BEGIN 的情况下永远存在
【发布时间】:2020-08-10 08:29:48
【问题描述】:

在根据条件打印数字后,AWK 中没有 BEGIN for 循环会永远消失 -

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

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

没有开始 -

$ 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 块将在程序开始时执行一次但没有开始,但一旦满足退出条件,命令不应该退出吗?

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

谢谢!

【问题讨论】:

    标签: awk


    【解决方案1】:

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

    【讨论】:

    • 它永远不会完成。我一直按回车键,循环继续进行,从未结束。如果每个输入行循环运行一个,那么它永远不会结束,对吗?
    • 照我说的做,想想你看到的输出,你提供一个输入行,然后循环运行并在5 打印后立即结束。然后您提供另一条输入线,循环再次运行(并结束)。当输入结束时,该过程结束。
    【解决方案2】:

    你问错问题了。

    第二次实验中的行为是意料之中的。您没有在命令行上指定文件名(或名称),因此awk 读取标准输入。它一次读取一行,直到到达文件末尾(就像从实际文件中读取一样)。并且,它执行您为每一行指定的规则;空行无关紧要。然后:ctrl-C是蛮力终止程序的不文明方式;正确的做法是发出ctrl-D,标记“文件”的结尾,让awk正常终止。

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

    “意外”行为出现在您的第一个实验中。同样,awk 从标准输入中读取;为什么不等待 EOF (ctrl-D) 退出,甚至认为 BEGIN 规则当然只会执行一次?

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

    如果一个awk 程序只有BEGIN 规则而没有其他规则,那么 BEGIN 规则运行后程序退出。

    您也可以喜欢阅读脚注:

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

    我会说“原始版本”正在做“正确的事情”,但这可能会让太多用户感到困惑,因此改变了行为。

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

    【讨论】:

    • The POSIX standard 说“如果 awk 程序仅包含具有模式 BEGIN 的操作,并且 BEGIN 操作不包含 getline 函数,则当最后一个 BEGIN 中的最后一条语句时,awk 将退出而不读取其输入动作被执行。”
    • @EdMorton - 不知何故,我一直觉得只有关于正则表达式的章节很容易访问。 (显然这是错误的,感谢您指出!)我唯一重要的计算经验是使用 Oracle SQL,可惜 SQL 标准不是免费提供的。对于 Unix/Linux,我将学习定期参考 POSIX 标准。谢谢!
    • 是的,我觉得几年前您至少必须订阅并创建一个登录名才能查看 POSIX 文档,但我可能记错了,无论如何这些天都不是真的。不客气。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    • 2021-11-18
    • 1970-01-01
    • 2017-03-25
    相关资源
    最近更新 更多