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.txtist 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-\x7Fwird 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, fileschlägt bei dieser Datei jedoch grob fehl. Nur das Entfernen eines Null-Bytes ( \0) (das technisch als ASCII gültig ist) und eines \x7fBytes (DEL - delete) (das eindeutig auch ein ASCII-Zeichen ist) macht die gesamte Datei für den fileBefehl 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 fileversä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, filekann UTF-8-codierten Text erkennen und melden:
$ echo "ééakjfhhjhfakjfhfhaéá" | file -
/dev/stdin: UTF-8 Unicode text
Außerdem werden die filemeisten Steuerzeichen im Bereich von 1 bis 31 nicht als ASCII gemeldet. fileEinige 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 fileist kein Werkzeug zum Erkennen von Text, sondern zum Erkennen magischer Zahlen in ausführbaren Programmen oder Dateien.
Die erkannten Bereiche fileund 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 1die 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 '�'
�
greplange versteht Unicode (was es viel langsamer macht, so dass die Suche nach ASCII-StringsLANG=C grepeine enorme Leistungsverbesserung ist).