Ich habe eine problematische Sequenz einer angeblich UTF-8-kodierten Textdatei gefunden. Das Seltsame dabei ist, dass grep diese nicht-ASCII-Zeile scheinbar nicht zuordnen kann.
$ 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
Dies \xe4
ist beispielsweise ä
im erweiterten ASCII-Satz der Fall. Das Filtern nach Steuer- und druckbaren Zeichen (ASCII-Bereich) der obige Grep-Befehl sollte mit dem \xe4
Zeichen übereinstimmen. Warum erhalte ich keine Grep-Ausgabe?
Antwort1
e4 75
ist in der Tat eine ungültige UTF8-Sequenz. In UTF8 führt ein Byte mit dem höchsten Nibble gleich 0xe eine Drei-Byte-Sequenz ein. Das zweite Byte einer solchen Sequenz kann nicht 0x75 sein, da das höchstwertige Nibble dieses zweiten Bytes (0x7) nicht zwischen 0x8 und 0xb liegt.
Dies erklärt, warum iconv diese Datei als ungültiges UTF8 ablehnt. Vielleicht ist sie bereits ISO8859-1?
Eine Zusammenfassung der UTF-8-Kodierung finden Sie hierWikipedia-Tabelle
Was Ihr Grep-Problem betrifft, gilt möglicherweise Folgendes, wenn Sie das C/POSIX-Gebietsschema angeben, bei dem Zeichen Bytes entsprechen:
LC_ALL=C grep -P -n '[^\x00-\x7F]' corrupt_part.txt
Verwenden eines alten Ubuntu-Systems, GNU grep und einer Umgebung mit dem Gebietsschema 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