2010-01-23 2 views
127

Unter Linux habe ich ein Verzeichnis mit vielen Dateien. Einige von ihnen haben Nicht-ASCII-Zeichen, aber sie sind alle gültig UTF-8. Ein Programm hat einen Fehler, der verhindert, dass es mit Nicht-ASCII-Dateinamen arbeitet, und ich muss herausfinden, wie viele davon betroffen sind. Ich würde dies mit find tun und dann eine grep, um die Nicht-ASCII-Zeichen zu drucken, und dann eine wc -l, um die Nummer zu finden. Es muss nicht Grep sein; Ich kann jeden Standard-Unix verwenden regular expression, wie Perl, sed, AWK usw.(grep) Regex für Nicht-ASCII-Zeichen?

Allerdings gibt es einen regulären Ausdruck für ‚jedes Zeichen, das nicht ein ASCII-Zeichen ist‘?

[^\x00-\x7F] 

Dies ist ein gültig PCRE (Perl-Compatible Regular Expression):

+2

ist Perl installiert? –

+1

Paul, ja ich kann perl verwenden – Rory

Antwort

221

Dies wird ein einziges Nicht-ASCII-Zeichen entspricht.

Sie können auch die POSIX Kürzeln verwenden:

  • [[:ascii:]] - entspricht einem einzelnen ASCII-Zeichen
  • [^[:ascii:]] - entspricht einem einzelnen Nicht-ASCII-Zeichen

[^[:print:]] wahrscheinlich ausreichen für Sie. **

+0

meinst du nicht [~ \ x20- \ x7f] – adrianm

+2

@adrianm: Nein, '^' ist in PCRE gültig. –

+10

Das stimmt genau. Sie müssen jedoch pcregrep verwenden, nicht standard grep. [^ [: print:]] funktioniert nicht, wenn Ihr Terminal in UTF8 eingerichtet ist. – Rory

4

Sie können auch diese Seite zu überprüfen: Unicode Regular Expressions, wie es einige nützliche Unicode-Zeichen-Klassen enthält, wie:

\p{Control}: an ASCII 0x00..0x1F or Latin-1 0x80..0x9F control character.
+0

[Standard-Grep unterstützt diese nicht] (https://www.gnu.org/software/grep/manual/grep.html). – eis

1

Es ist nicht wirklich eine Regex benötigen.

Dies zeigt Dateinamen mit Steuerzeichen in ihren Namen, aber ich halte das für ein Feature.

Wenn Sie keine übereinstimmenden Dateien haben, wird der Glob auf nichts erweitert.

+1

Seltsamerweise funktioniert das nicht richtig in Bash. – tripleee

26

Nein, [^\x20-\x7E] ist kein ASCII.

Dieses echte ASCII:

[^\x00-\x7F] 

Ansonsten wird es Zeilenumbrüche und andere Sonderzeichen trimmen, die Teil der ASCII-Tabelle sind!

0

können Sie diese Regex verwenden:

[^\w \xC0-\xFF] 

Fall fragen, ist die Optionen mehrzeilige.

0

Dies erwies sich als sehr flexibel und erweiterbar. $ field = ~ s/[^ \ x00- \ x7F] // g; # Somit konnten alle nicht ASCII- oder spezifischen Elemente bereinigt werden. Sehr schön entweder bei der Auswahl oder Vorverarbeitung von Elementen, die schließlich zu Hash-Schlüsseln werden.

1

[^\x00-\x7F] und [^[:ascii:]] verpassen einige Steuerbytes, so strings kann manchmal die bessere Option sein. Zum Beispiel cat test.torrent | perl -pe 's/[^[:ascii:]]+/\n/g' wird seltsame Dinge zu Ihrem Terminal machen, wo sich strings test.torrent verhalten wird.