awk getline 跳到最后一行——可能的换行符问题

发布于 2024-12-10 07:34:50 字数 335 浏览 0 评论 0原文

我在 BEGIN 语句中使用

while( (getline line < "filename") > 0 )

,但是这个 while 循环似乎只读取文件的最后一行而不是每一行。我认为这可能是换行符问题,但我真的不知道。有什么想法吗?

我正在尝试从主输入文件以外的文件读取数据。

相同的语法实际上适用于一个文件,但不适用于另一个文件,我看到的唯一区别是,当我在 Vim 中查看它时,它适用的文件在每一行的末尾都有“^M”,而它不起作用的地方没有 ^M。但这在我的(基于 UNIX 的)Mac 上似乎是一个奇怪的问题。

我希望我比我更了解 getline 的情况。

I'm using

while( (getline line < "filename") > 0 )

within my BEGIN statement, but this while loop only seems to read the last line of the file instead of each line. I think it may be a newline character problem, but really I don't know. Any ideas?

I'm trying to read the data in from a file other than the main input file.

The same syntax actually works for one file, but not another, and the only difference I see is that the one for which it DOES work has "^M" at the end of each line when I look at it in Vim, and the one for which it DOESN'T work doesn't have ^M. But this seems like an odd problem to be having on my (UNIX based) Mac.

I wish I understood what was going with getline a lot better than I do.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清风不识月 2024-12-17 07:34:50

您必须将 RS 指定为更模糊的内容。
这是一个丑陋的黑客让事情正常工作

RS="[\x0d\x0a\x0d]"

现在,这可能需要一些解释。
不同的系统使用不同的方式来处理线路变更。
阅读 http://en.wikipedia.org/wiki/Carriage_returnhttp://en.wikipedia.org/wiki/Newline 如果您是
对它感兴趣。

通常 awk 会优雅地处理这个问题,但在您的环境中,某些文件似乎很顽皮。
0x0d 或 0x0a 或 0x0d 0x0a (CR+LF) 应该存在,但不能混合。

因此,让我们尝试一个混合数据流的示例

$ echo -e "foo\x0d\x0abar\x0d\x0adoe\x0arar\x0azoe\x0dqwe\x0dtry" |awk 'BEGIN{while((getline r )>0){print "r=["r"]";}}'

结果:

r=[foo]
r=[bar]
r=[doe]
r=[rar]
try]oe

我们可以看到最后几行丢失了。
现在使用丑陋的破解 RS

$ echo -e "foo\x0d\x0abar\x0d\x0adoe\x0arar\x0azoe\x0dqwe\x0dtry" |awk 'BEGIN{RS="[\x0d\x0a\x0d]";while((getline r )>0){print "r=["r"]";}}'

结果:

r=[foo]
r=[bar]
r=[doe]
r=[rar]
r=[zoe]
r=[qwe]
r=[try]

我们可以看到每一行都已获得,不管 0x0d 0x0a 垃圾:-)

You would have to specify RS to something more vague.
Here is a ugly hack to get things working

RS="[\x0d\x0a\x0d]"

Now, this may require some explanation.
Diffrent systems use difrent ways to handle change of line.
Read http://en.wikipedia.org/wiki/Carriage_return and http://en.wikipedia.org/wiki/Newline if you are
interested in it.

Normally awk hadles this gracefully, but it appears that in your enviroment, some files are being naughty.
0x0d or 0x0a or 0x0d 0x0a (CR+LF) should be there, but not mixed.

So lets try a example of a mixed data stream

$ echo -e "foo\x0d\x0abar\x0d\x0adoe\x0arar\x0azoe\x0dqwe\x0dtry" |awk 'BEGIN{while((getline r )>0){print "r=["r"]";}}'

Result:

r=[foo]
r=[bar]
r=[doe]
r=[rar]
try]oe

We can see that the last lines are lost.
Now using the ugly hack to RS

$ echo -e "foo\x0d\x0abar\x0d\x0adoe\x0arar\x0azoe\x0dqwe\x0dtry" |awk 'BEGIN{RS="[\x0d\x0a\x0d]";while((getline r )>0){print "r=["r"]";}}'

Result:

r=[foo]
r=[bar]
r=[doe]
r=[rar]
r=[zoe]
r=[qwe]
r=[try]

We can see every line is obtained, reguardless of the 0x0d 0x0a junk :-)

把回忆走一遍 2024-12-17 07:34:50

也许您应该使用例如 dos2unix 预处理您的输入文件(http://sourceforge.net/projects/dos2unix/) 效用?

Maybe you should preprocess your input file with for example dos2unix (http://sourceforge.net/projects/dos2unix/) utility?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文