Grep 不匹配非 ASCII 字符

Grep 不匹配非 ASCII 字符

我发现了一个被认为是 UTF-8 编码的文本文件的有问题的序列。奇怪的是 grep 似乎无法匹配这个非 ASCII 行。

$ iconv -f utf8 -t iso88591 corrupt_part.txt --output corrupt_part.txt.conv
iconv: illegal input sequence at position 8
$ cat corrupt_part.txt
Oberallg�u
$ grep -P -n '[^\x00-\x7F]' corrupt_part.txt
$ od -h corrupt_part.txt
0000000 624f 7265 6c61 676c 75e4 0a20
0000014

\xe4例如,ä在扩展 ASCII 集中也是如此。然而,过滤控制和可打印字符(ASCII 范围) 上面的 grep 命令应该与该\xe4字符匹配。为什么我没有得到任何 grep 输出?

答案1

e4 75确实是非法的utf8序列。在utf8中,最高半字节等于0xe的字节引入了三字节序列。该序列的第二个字节不能是 0x75,因为第二个字节的高位半字节 (0x7) 不在 0x8 和 0xb 之间。

这解释了为什么 iconv 拒绝该文件作为无效的 utf8。也许它已经是 iso8859-1 了?

有关 utf8 编码的摘要,请参阅此维基百科表

至于你的 grep 问题,也许如果你指定 C/POSIX 语言环境,其中字符相当于字节:

LC_ALL=C grep -P -n '[^\x00-\x7F]' corrupt_part.txt

使用旧的 Ubuntu 系统、GNU grep 和使用 en_US.UTF-8 语言环境的环境:

$ od -h bytes
0000000 624f 7265 6c61 676c 75e4 0a20
0000014
$ grep -P '[^\x00-\x7F]' bytes | od -h
0000000 624f 7265 6c61 676c 75e4 0a20
0000014
$ LC_ALL=C grep -P '[^\x00-\x7F]' bytes | od -h
0000000 624f 7265 6c61 676c 75e4 0a20
0000014

相关内容