TL; DR:
grep -axv '.*' out.txt
lange Antwort
Beide vorliegenden Antworten sind äußerst irreführend und grundsätzlich falsch.
Holen Sie sich zum Testen diese beiden Dateien (von einem sehr angesehenen Entwickler: Markus Kuhn):
$ wget https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt
$ wget https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
Demo
Die erste UTF-8-demo.txt
ist eine Datei, die zeigen soll, wie gut UTF-8 viele Sprachen, Mathematik, Braille und viele andere nützliche Zeichentypen darstellen kann. Werfen Sie einen Blick mit einem Texteditor (der utf-8 versteht) und Sie werden viele Beispiele sehen und nein �
.
Der Test, den eine Antwort vorschlägt: Um den Zeichenbereich auf zu beschränken, \x00-\x7F
wird fast alles in dieser Datei abgelehnt.
Das ist sehr falsch und wird keine entfernen, �
da es keine in dieser Datei gibt .
Wenn Sie den in dieser Antwort empfohlenen Test verwenden, wird 72.5 %
die Datei entfernt:
$ grep -oP "[^\x00-\x7F]" UTF-8-demo.txt | tr -d '\n' | wc -c
10192
$ cat UTF-8-demo.txt | wc -c
14058
Das ist (für die meisten praktischen Zwecke) die gesamte Datei. Eine Datei, die sehr gut gestaltet ist, um perfekt gültige Zeichen anzuzeigen.
Prüfung
Die zweite Datei soll mehrere Grenzfälle versuchen, um zu bestätigen, dass utf-8-Leser gute Arbeit leisten. Es enthält viele Zeichen, die dazu führen, dass ein ' ' angezeigt wird. Die andere Antwortempfehlung (die ausgewählte), die verwendet werden soll, file
schlägt bei dieser Datei jedoch grob fehl. Nur das Entfernen eines Null-Bytes ( \0
) (das technisch als ASCII gültig ist) und eines \x7f
Bytes (DEL - delete) (das eindeutig auch ein ASCII-Zeichen ist) macht die gesamte Datei für den file
Befehl gültig :
$ cat UTF-8-test.txt | tr -d '\0\177' > a.txt
$ file a.txt
a.txt: Non-ISO extended-ASCII text, with LF, NEL line terminators
Nicht nur file
versäumt es, die vielen zu erkennen falschen Zeichen , sondern es wird auch nicht erkannt und gemeldet, dass es sich um eine UTF-8-codierte Datei handelt.
Und ja, file
kann UTF-8-codierten Text erkennen und melden:
$ echo "ééakjfhhjhfakjfhfhaéá" | file -
/dev/stdin: UTF-8 Unicode text
Außerdem werden die file
meisten Steuerzeichen im Bereich von 1 bis 31 nicht als ASCII gemeldet. file
Einige Bereiche werden wie folgt gemeldet data
:
$ printf '%b' "$(printf '\\U%x' {1..6})" | file -
/dev/stdin: data
Andere als ASCII text
:
$ printf '%b' "$(printf '\\U%x' 7 {9..12})" | file -
/dev/stdin: ASCII text
Als druckbarer Zeichenbereich (mit Zeilenumbrüchen):
$ printf '%b' "$(printf '\\U%x' {32..126} 10)" | file -
/dev/stdin: ASCII text
Einige Bereiche können jedoch zu seltsamen Ergebnissen führen:
$ printf '%b' "$(printf '\\U%x' {14..26})" | file -
/dev/stdin: Atari MSA archive data, 4113 sectors per track, starting track: 5141, ending track: 5655
Das Programm file
ist kein Werkzeug zum Erkennen von Text, sondern zum Erkennen magischer Zahlen in ausführbaren Programmen oder Dateien.
Die erkannten Bereiche file
und der entsprechende Typ, den ich gefunden habe, waren:
Ein-Byte-Werte, meistens ASCII:
{1..6} {14..26} {28..31} 127 :data
{128..132} {134..159} :Non-ISO extended-ASCII text
133 :ASCII text, with LF, NEL line terminators
27 :ASCII text, with escape sequences
13 :ASCII text, with CR, LF line terminators
8 :ASCII text, with overstriking
7 {9..12} {32..126} :ASCII text
{160..255} :ISO-8859 text
Utf-8-codierte Bereiche:
{1..6} {14..26} {28..31} 127 :data
27 :ASCII text, with escape sequences
13 :ASCII text, with CR, LF line terminators
8 :ASCII text, with overstriking
7 {9..12} {32..126} :ASCII text
{128..132} {134..159} :UTF-8 Unicode text
133 :UTF-8 Unicode text, with LF, NEL line terminators
{160..255} :UTF-8 Unicode text
{256..5120} :UTF-8 Unicode text
Eine mögliche Lösung liegt unten.
Vorherige Antwort.
Der Unicode-Wert für das Zeichen, das Sie veröffentlichen, lautet:
$ printf '%x\n' "'�"
fffd
Ja, das ist ein Unicode-Zeichen 'REPLACEMENT CHARACTER' (U + FFFD) . Dies ist ein Zeichen, das verwendet wird, um ungültige Unicode-Zeichen im Text zu ersetzen . Es ist eine "visuelle Hilfe", kein wirklicher Charakter. Um jede vollständige Zeile zu finden und aufzulisten , die ungültige UNICODE- Zeichen enthält , verwenden Sie:
grep -axv '.*' out.txt
Wenn Sie jedoch nur feststellen möchten, ob ein Zeichen ungültig ist, verwenden Sie:
grep -qaxv '.*' out.txt; echo $?
Wenn das Ergebnis ist, dass 1
die Datei sauber ist, ist sie ansonsten Null 0
.
Wenn Sie gefragt haben, wie Sie den �
Charakter finden, verwenden Sie Folgendes:
➤ a='Basically, if the file "out.txt" contains "�" anywhere in the file I'
➤ echo "$a" | grep -oP $(printf %b \\Ufffd)
�
Oder wenn Ihr System UTF-8-Text korrekt verarbeitet, einfach:
➤ echo "$a" | grep -oP '�'
�
grep
lange versteht Unicode (was es viel langsamer macht, so dass die Suche nach ASCII-StringsLANG=C grep
eine enorme Leistungsverbesserung ist).