429 Stimmen

Wie kann ich nach allen Nicht-ASCII-Zeichen fahnden?

Ich habe mehrere sehr große XML-Dateien, und ich versuche, die Zeilen zu finden, die Nicht-ASCII-Zeichen enthalten. Ich habe das Folgende versucht:

grep -e "[\x{00FF}-\x{FFFF}]" file.xml

Dies gibt jedoch jede Zeile in der Datei zurück, unabhängig davon, ob die Zeile ein Zeichen in dem angegebenen Bereich enthält.

Habe ich die Syntax falsch oder mache ich etwas anderes falsch? Ich habe es auch versucht:

egrep "[\x{00FF}-\x{FFFF}]" file.xml 

(wobei das Muster sowohl in einfachen als auch in doppelten Anführungszeichen steht).

588voto

jerrymouse Punkte 15398

Sie können den Befehl verwenden:

grep --color='auto' -P -n "[\x80-\xFF]" file.xml

Dies gibt die Zeilennummer an und hebt Nicht-ASCI-Zeichen rot hervor.

Auf manchen Systemen, abhängig von den Einstellungen, funktioniert das nicht, daher können Sie grep durch die Umkehrung

grep --color='auto' -P -n "[^\x00-\x7F]" file.xml

Beachten Sie auch, dass der wichtige Teil die -P Flagge, die gleichbedeutend ist mit --perl-regexp : Damit wird Ihr Muster als regulärer Ausdruck in Perl interpretiert. Es sagt auch, dass

Dies ist höchst experimentell und grep -P kann vor nicht implementierten Funktionen warnen.

155voto

pvandenberk Punkte 4459

Anstatt Annahmen über den Byte-Bereich von Nicht-ASCII-Zeichen zu machen, wie es die meisten der oben genannten Lösungen tun, ist es IMO etwas besser, den tatsächlichen Byte-Bereich von ASCII-Zeichen explizit anzugeben.

Die erste Lösung wäre also zum Beispiel:

grep --color='auto' -P -n '[^\x00-\x7F]' file.xml

(das grundsätzlich nach jedem Zeichen außerhalb des hexadezimalen ASCII-Bereichs sucht: von \x00 bis zu \x7F )

Unter Mountain Lion funktioniert das nicht (wegen der fehlenden PCRE-Unterstützung in BSD grep) sondern mit pcre über Homebrew installiert wurde, funktioniert das Folgende genauso gut:

pcregrep --color='auto' -n '[^\x00-\x7F]' file.xml

Kann sich jemand Vor- oder Nachteile vorstellen?

75voto

Der einfache Weg ist, ein Nicht-ASCII-Zeichen zu definieren... als ein Zeichen, das kein ASCII-Zeichen ist.

LC_ALL=C grep '[^ -~]' file.xml

Fügen Sie eine Registerkarte nach der ^ falls erforderlich.

Einstellung LC_COLLATE=C vermeidet böse Überraschungen bezüglich der Bedeutung von Zeichenbereichen in vielen Ländern. Einstellung LC_CTYPE=C ist notwendig, um Einzelbyte-Zeichen abzugleichen - andernfalls würde der Befehl ungültige Bytefolgen in der aktuellen Kodierung übersehen. Einstellung LC_ALL=C vermeidet ortsabhängige Effekte gänzlich.

68voto

Thelema Punkte 13287

Bei mir funktioniert das wie folgt:

grep -P "[\x80-\xFF]" file.xml

Nicht-ASCII-Zeichen beginnen bei 0x80 und gehen bis 0xFF, wenn man die Bytes betrachtet. Grep (und die Grep-Familie) führen keine Unicode-Verarbeitung durch, um Multi-Byte-Zeichen zu einer einzigen Einheit für den Regex-Abgleich zusammenzufassen, wie Sie es anscheinend wünschen. Die -P Option in meinem grep erlaubt die Verwendung von \xdd Escapes in Zeichenklassen, um zu erreichen, was Sie wollen.

62voto

noquery Punkte 1835

In Perl

perl -ane '{ if(m/[[:^ascii:]]/) { print  } }' fileName > newFile

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X