getline
指定读取“来自当前输入文件”并在文件末尾返回 0。gawk和POSIX文档都使用这种措辞。这是有道理的:数据可能出于某种原因在文件之间分配。如果可以区分文件,语言会更具表现力。结构足够合理的信息通常不会跨越文件边界。getline
getline
但是 GNU 和 macOS/BSD 实现都隐藏了 EOF 并立即打开下一个文件。这样做会更新FILENAME
,而这不在 GNU 或 POSIX 文档中指定受影响的变量列表中。
我看到的唯一解决方法是确保每个文件都以一个一次性的行开头,并检测何时FNR
重置为 1。真恶心。
这两种实现都存在此错误,这真是一个奇怪的巧合。查看源代码,这两种行为都不是疏忽。两者都采取了特定的步骤来推进文件,而不是getline
从命名的 I/O 句柄进行代码分支。冗长的 GNU 文档与此行为相矛盾,这尤其奇怪。
我是不是漏掉了什么?我是不是偶然发现了一个不常见的案例,或者这是 Awk 传说中已知的?
听起来你只是想要一种方法来知道循环何时
getline
到达文件末尾,所以这里有一种方法可以做到这一点。使用这些包含 1 个空文件的输入文件(在任何 awk 中都不是不可能处理,但如果没有 awk 则很难处理,
ENDFILE
因为getline
在尝试读取该空文件和读取下一个文件的第一行之间不会返回,并且ARGV[]
可能包含与文件名混合的变量分配,并且可能包含同一文件名的多次出现):使用 GNU awk 你可以执行以下操作:
但是如果没有您要解决的问题的具体例子,我不知道这是否可以解决问题。
顺便一提...
文档应该说“输入结束”而不是“文件结束”。如果您愿意,可以向 gawk 提供商提交错误报告,请参阅https://www.gnu.org/software/gawk/manual/gawk.html#Bug-address,和/或 POSIX 人员,请参阅http://www.opengroup.org/austin/。
您在问题中说:
但是 GNU awk 手册在“关于 getline 的要点”部分中说明了以下内容:
不过, AllAboutGetline*文章中受影响变量的表中已经明确说明了这一点。
*关于Getline
如果您考虑使用,请务必阅读http://awk.freeshell.org/AllAboutGetline (如果该网站已关闭,请参阅https://web.archive.org/web/20221109201352/http://awk.freeshell.org/AllAboutGetline上的存档)
getline
。