Grep

Grep 不匹配非 ASCII 字元

  • February 16, 2016

我發現了一個應該是 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 輸出?

e4 75確實是非法的utf8序列。在 utf8 中,最高半字節等於 0xe 的字節引入了一個三字節序列。這種序列的第二個字節不能是 0x75,因為第二個字節 (0x7) 的高位半字節不在 0x8 和 0xb 之間。

這解釋了為什麼 iconv 將該文件拒絕為無效的 utf8。也許它已經是iso8859-1?

有關 utf8 編碼的摘要,請參閱此wikipedia table

至於您的 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

引用自:https://unix.stackexchange.com/questions/263691