web-dev-qa-db-ja.com

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 range )でのフィルタリングは、上記のgrepコマンドが\xe4文字と一致する必要があります。なぜ私はそうではないのですか? grep出力を取得していますか?

2
bioslime

e4 75は確かに違法なutf8シーケンスです。 utf8では、最高のニブルが0xeに等しいバイトは、3バイトのシーケンスを導入します。そのようなシーケンスの2番目のバイトは0x75にすることはできません。これは、その2番目のバイト(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
4
Barefoot IO