首页 > 解决方案 > 使用 awk 在文件中搜索十六进制值时,版本 4.0 和 4.1 的不同行为

问题描述

我试图在这样的文件中找到一串十六进制值:

$ awk '/\x00\x01\x02\x03/ {exit 1;}' myfile.bin
$ echo $?

我确信文件包含这样的值,因为我可以在 VI 中看到它们(在 hexdump 模式下)

00000000: ad33 0215 0001 0203 e1fa 8f76 1941 cd07  ....
......

如果我awk在具有 4.1.3 版(Ubuntu 16.04.3 LTS)的机器上使用它,它可以工作(返回 1)。对于awk版本 4.0.3(在 Ubuntu 14.04.5 LTS 机器上),它返回 0。

在这两种情况下使用的文件是相同的(实际上安装在两台机器的 NAS 上)。我还检查了awk's changelog,但无济于事。

标签: bashubuntuawk

解决方案


使用您的真实数据可能无法做到这一点,但我能够重现您的错误并创建更可靠的替换代码。它也应该更快,因为它避免了正则表达式。

首先,让我们创建一个可重现的测试:

$ awk 'BEGIN{printf "%c%c%c%c", 0, 1, 2, 3}' > myfile.bin
$ hexdump -C myfile.bin
00000000  00 01 02 03                                       |....|
00000004

好的,现在我们可以测试一下:

[gawk 4.0.2]$ gawk --version |awk NR==1
GNU Awk 4.0.2
[gawk 4.0.2]$ gawk '/\x00\x01\x02\x03/ {exit 1}' myfile.bin; echo $?
0

在另一个系统上:

[gawk 4.1.4]$ gawk --version |awk NR==1
GNU Awk 4.1.4, API: 1.1 (GNU MPFR 4.0.1, GNU MP 6.1.2)
[gawk 4.1.4]$ gawk '/\x00\x01\x02\x03/ {exit 1}' myfile.bin; echo $?
1

转载。

让我们使用index()而不是正则表达式:

[gawk 4.0.2]$ gawk 'index($0, "\x00\x01\x02\x03") { exit 1 }' myfile.bin; echo $?
1

 

[gawk 4.1.4]$ gawk 'index($0, "\x00\x01\x02\x03") { exit 1 }' myfile.bin; echo $?
1

推荐阅读