(grep) Regex für Nicht-ASCII-Zeichen?

169

Unter Linux habe ich ein Verzeichnis mit vielen Dateien. Einige von ihnen haben Nicht-ASCII-Zeichen, aber alle sind gültige UTF-8 -Zeichen . Ein Programm hat einen Fehler, der verhindert, dass es mit Nicht-ASCII-Dateinamen funktioniert, und ich muss herausfinden, wie viele davon betroffen sind. Ich wollte dies mit tun findund dann ein Grep machen , um die Nicht-ASCII-Zeichen zu drucken, und dann ein wc -l, um die Nummer zu finden. Es muss nicht grep sein; Ich kann jeden regulären Unix-Standardausdruck wie Perl , sed , AWK usw. verwenden.

Gibt es jedoch einen regulären Ausdruck für "ein Zeichen, das kein ASCII-Zeichen ist"?

Rory
quelle
1
Paul, ja, ich kann Perl benutzen
Rory
/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]
Tinmarino

Antworten:

310

Dies entspricht einem einzelnen Nicht-ASCII-Zeichen:

[^\x00-\x7F]

Dies ist eine gültige PCRE ( Perl-kompatibler regulärer Ausdruck ).

Sie können auch die POSIX- Abkürzungen verwenden:

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

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

Alix Axel
quelle
3
@adrianm: Nein, ^ist in PCRE gültig.
Alix Axel
10
Das ist genau richtig. Sie müssen jedoch pcregrep verwenden, nicht Standard-Grep. [^ [: print:]] funktioniert nicht, wenn Ihr Terminal in UTF8 eingerichtet ist.
Rory
@Rory, warum :print:funktioniert das nicht in einem UTF8-Terminal? Dies funktioniert für mich in Pry in einem UTF8-Terminal:27.chr =~ /[^[:print:]]/
Akostadinov
Dies ist wirklich hilfreich, um fehlerhafte Dateinamen zu beheben - rename 's/[^\x00-\x7F]//g' *(Sie können -ndamit überprüfen, ob die Umbenennungen in Ordnung sind).
naught101
Wie kann ich Zeichen, die nicht UTF8 sind, und andere bestimmte Zeichen zuordnen?
CMCDragonkai
37

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

Das ist echtes ASCII:

 [^\x00-\x7F]

Andernfalls werden Zeilenumbrüche und andere Sonderzeichen, die Teil der ASCII-Tabelle sind, abgeschnitten!

Peter L.
quelle
3

[^\x00-\x7F]und [^[:ascii:]]einige Kontrollbytes verpassen, so dass Strings manchmal die bessere Option sein können. Zum Beispiel cat test.torrent | perl -pe 's/[^[:ascii:]]+/\n/g'werden seltsame Dinge an Ihrem Terminal getan, wo strings test.torrentsich dies verhält.

user1133275
quelle
3

So überprüfen Sie das Textfeld Akzeptieren Sie Ascii Verwenden Sie nur dieses Muster

[\x00-\x7F]+

Othman Mahmoud
quelle
3

Ich benutze [^\t\r\n\x20-\x7E]+und das scheint gut zu funktionieren.

SolidSnakeUk89
quelle
2

Sie können diesen regulären Ausdruck verwenden:

[^\w \xC0-\xFF]

Bei Fragen fragen, die Optionen sind mehrzeilig .

CypherPotato
quelle
2

Du brauchst nicht wirklich einen regulären Ausdruck.

printf "%s\n" *[!\ -~]*

Dies zeigt auch Dateinamen mit Steuerzeichen in ihren Namen an, aber ich halte das für eine Funktion.

Wenn Sie keine passenden Dateien haben, wird der Glob auf sich selbst erweitert, sofern Sie nichts festgelegt haben nullglob. (Der Ausdruck stimmt nicht mit sich selbst überein, daher ist diese Ausgabe technisch eindeutig.)

Tripleee
quelle
Ich kann Verspätet, feststellen , dass dies tut richtig funktioniert , wenn Sie tatsächlich einige Dateien haben , die diesem Muster entsprechen. Das Verhalten, bei dem sich das Muster selbst druckt, wenn keine Übereinstimmungen vorliegen, ist etwas überraschend, aber tatsächlich korrekt. Ich habe die Antwort bearbeitet, um dies hoffentlich zu klären.
Tripleee
1

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

Don Turnblade
quelle