这是交易:我需要读取特定字节数,稍后将对其进行处理。我遇到了一个奇怪的现象,我无法绕过它。也许别人? :)
注意:以下代码示例是精简版本,只是为了显示效果!
这样做(至少使用gawk
)是将RS
设置为全部正则表达式,然后使用RT
查看,匹配的内容:
RS="[\x00-\xFF]"
然后,只需使用以下 awk-script :
BEGIN {
ORS=""
OFS=""
RS="[\x00-\xFF]"
}
{
print RT
}
这很好用:
$ echo "abcdef" | awk -f bug.awk
abcdef
但是,我需要访问几个文件,因此我被迫使用getline
:
BEGIN {
ORS=""
OFS=""
RS="[\x00-\xFF]"
while (getline)
{
print RT
}
}
这似乎等同于上面的内容,但在运行时,有一个令人讨厌的惊喜:
$ echo "abcdef" | awk -f bug.awk
abc
这意味着,由于某种原因,getline
早期遇到EOF条件 3个字节。那么,我是否想念一些东西,我应该知道 bash / Linux 缓冲的内部结构,还是我发现了一个可怕的 bug ?
仅供记录:我在Ubuntu 14.04 LTS(Linux 3.13.0 / 36)上使用GNU Awk 4.0.1
任何提示,伙计们?
更新:我正在使用getline
,因为我之前已经阅读并预处理了文件,并存储在文件/dev/shm/
中。然后我需要做一些最后的处理步骤。上面的示例只是最简单的脚本,以显示问题。
答案 0 :(得分:1)
似乎这是报告错误here的一种表现形式,如果我理解正确的话,它会在接近输入结束时过早地终止getline
,而不是输入的结束。
错误修复似乎已在2014年May 9和May 10上提交,因此如果您可以升级到版本4.1,则应该解决问题。
如果你需要做的只是读取指定的字节数,我建议awk
不是理想的工具,不管错误。相反,您可以考虑以下两个标准实用程序之一,它们将能够更有效地完成工作:
head -c $count
或
dd bs=$count count=1
使用dd
,如果stdin / stdout不合适,您可以显式设置输入文件(if=PATH
)和输出文件(of=PATH
)。使用head
,您可以将输入文件指定为位置参数,但输出始终转到stdout。
答案 1 :(得分:0)
幸运的是,使用GNU Awk 4.1.3(在Mac上),你的getline程序按预期工作:
echo "abcdef" | gawk 'BEGIN{ORS="";OFS="";RS="[\x00-\xFF]";
while (getline) {print RT}}'
abcdef
$ gawk --version
GNU Awk 4.1.3, API: 1.1