awk中如何检测EOF?
有没有办法判断当前行是否是输入流的最后一行?
Is there a way to determine whether the current line is the last line of the input stream?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
有没有办法判断当前行是否是输入流的最后一行?
Is there a way to determine whether the current line is the last line of the input stream?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(11)
gawk 实现有一个名为
ENDFILE
的特殊规则,它将在处理每个参数列表中的文件。这是有效的:更多详细信息您可以在此处>>找到
gawk implementation has special rule called
ENDFILE
which will be triggered after processing every file in argument list. This works:more details you can find here>>
当命令行上有多个文件时,检测 EOF 不太可靠。检测文件的开头更加可靠。
为此,第一个文件是特殊的,我们忽略 FNR==1。
在第一个文件之后,FNR==1 成为前一个文件的结尾。 last_filename 始终具有您正在处理的文件名。
在其他之后进行文件处理。
在 else 块和 END 块中进行 EOF 处理。
对于多个文件集,除了最后一个文件之外的所有文件的 else 块都会在 EOF 处执行。最后一个文件在 END 块中执行。
对于单个文件集,不会执行 else 块,而是执行 END 块。
Detecting the EOF is not too reliable when multiple files are on the command line. Detecting the start of the file is more reliable.
To do this, the first file is special and we ignore the FNR==1.
After the first file then FNR==1 becomes the end of the previous file. last_filename always has the filename that you are processing.
Do your file processing after the else.
Do your EOF processing inside the else block, AND in the END block.
For multiple file sets, the else block executes at EOF for all but the last file. The last file is executed in the END block.
For single file sets, the else block doesn't get executed, and the END block is executed.
我什至不知道如何对这个“解决方案”进行分类
这个黑客的酷之处在于,通过分配给
$0
,所有剩余的声明模式和操作都可以工作,只是延迟了一行。即使您将END
放在顶部,您也无法让它们为END
工作,但您确实可以控制最后一个线,并且您没有对其执行任何其他操作。I'm not even sure how to categorize this "solution"
The cool thing about this hack is that by assigning to
$0
, all the remaining declarative patterns and actions work, one line delayed. You can't get them to work for theEND
, even if you put theEND
on top, but you do have control on the last line and you haven't done anything else to it.一种简单的方法是通过中间
sed
脚本运行文件,该脚本在非最后一行上放置 0,在最后一行放置 1。One easy way is to run the file via an intermediate
sed
script, that places a 0 on every non last line, and a 1 on the last one.检测参数列表中每个文件的最后一行
以下效果很好:
To detect the last line of each file in the argument list
the following works nicely:
嗯,awk
END
变量会告诉您何时已经到达EOF
。我想对你来说并没有多大帮助Hmm the awk
END
variable tells when you have already reached theEOF
. Isn't really much of help to you I guess你可以试试这个:
you can try this:
gawk 用户手册中提供了便携式解决方案,虽然在另一个答案中提到,gawk本身有BEGINFILE和ENDFILE。
A portable solution is provided in the gawk user manual, although as mentioned in another answer, gawk itself has BEGINFILE and ENDFILE.
这些是做你想做的事情的唯一明智的方法,按最好到最差的顺序排列:
These are the only sensible ways to do what you want, in order of best to worst:
特殊的
END
模式仅在所有输入结束后匹配。请注意,此模式不能与任何其他模式组合。更有用的可能是 getline 伪函数,它将 $0 重置到下一行并返回 1,或者在 EOF 的情况下返回 0!我认为这就是你想要的。
例如:
如果您只处理一个文件,则这将是等效的:
The special
END
pattern will match only after the end of all input. Note that this pattern can't be combined with any other pattern.More useful is probably the
getline
pseudo-function which resets$0
to the next line and return 1, or in case of EOF return 0! Which I think is what you want.For example:
If you are only processing one file, this would be equivalent:
你有两个选择,都有点混乱。
您可能需要稍微尝试一下#2 才能让它运行,但它应该可以工作。我已经有一段时间没有做过 awk 了。
You've got two options, both kind of messy.
You might have to play with #2 a little to get it to run, but it should work. Its been a while since I've done any awk.