GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Tr Analog für Unicode-Zeichen?

Ich brauche ein internationalisiertes Dienstprogramm, das dasselbe tut wie tr :Ruft Zeichen aus Stream ab und ersetzt es durch ein entsprechendes Zeichen.
Es wird keine Sonderfalllösung wie Lower-to-Upper, sondern eine allgemeine Falllösung benötigt.
Ohne gorillion piped sed ruft wenn möglich an.

Beachten Sie, dass tr funktioniert nicht unter Linux:Es übersetzt Bytes, keine Zeichen. Dies schlägt bei Multibyte-Kodierungen fehl.

$ tr --version | head -n 1
tr (GNU coreutils) 8.23
$ echo $LC_CTYPE
en_US.UTF-8
$ echo 'Ångstrom' | tr Æ Œ         
Ņngstrom

Akzeptierte Antwort:

GNU sed funktioniert mit Multi-Byte-Zeichen. Also:

$ echo é½Æ | sed 'y/é½Æ/ABŒ/'
ABŒ

Es ist nicht so sehr, dass GNU tr nicht internationalisiert wurde, aber keine Multi-Byte-Zeichen unterstützt (wie die Nicht-ASCII-Zeichen in UTF-8-Locales). GNU tr würde mit Æ funktionieren , Œ solange sie Single-Byte wie im Zeichensatz iso8859-15 sind.

Mehr dazu unter Wie mache ich tr auf Nicht-ASCII-Zeichen (Unicode) aufmerksam?

Das hat jedenfalls nichts mit Linux zu tun, sondern mit dem tr Implementierung auf dem System. Ob dieses System Linux als Kernel oder tr verwendet für Linux erstellt wurde oder die Linux-Kernel-API verwendet, ist nicht relevant, da dieser Teil des tr nicht relevant ist Funktionalität findet im Benutzerbereich statt.

Busybox tr und GNU tr sind am häufigsten in Distributionen von Software zu finden, die für Linux erstellt wurde, und unterstützen keine Multibyte-Zeichen, aber es gibt andere, die nach Linux portiert wurden, wie tr der Heirloom-Toolchest (portiert von OpenSolaris) oder von ast-open, die dies tun.

Beachten Sie, dass sed ist y unterstützt keine Bereiche wie a-z . Beachten Sie auch, dass, wenn das Skript, das sed 'y/é½Æ/ABŒ/' enthält, perl sein :

perl -Mopen=locale -Mutf8 -pe 'y/a-zé½Æ/A-ZABŒ/'

Oben wird erwartet, dass der Perl-Code in UTF-8 vorliegt, aber er wird die Eingabe in der Codierung des Gebietsschemas verarbeiten (und in derselben Codierung ausgeben). Wenn es in einem UTF-8-Gebietsschema aufgerufen wird, transliteriert es ein UTF-8 Æ (0xc3 0x86) zu einem UTF-8 Œ (0xc5 0x92) und in einem ISO8859-15 gleich, aber für 0xc6 -> 0xbc.

In den meisten Shells sollte es in Ordnung sein, diese UTF-8-Zeichen in einfachen Anführungszeichen zu haben, selbst wenn das Skript in einem Gebietsschema aufgerufen wird, in dem UTF-8 nicht der Zeichensatz ist (eine Ausnahme ist yash was sich beschweren würde, wenn diese Bytes keine gültigen Zeichen im Gebietsschema bilden). Wenn Sie jedoch andere Anführungszeichen als einfache Anführungszeichen verwenden, kann dies zu Problemen führen. Zum Beispiel

perl -Mopen=locale -Mutf8 -pe "y/♣`/&'/"

würde in einem Gebietsschema fehlschlagen, in dem der Zeichensatz BIG5-HKSCS ist, da die Codierung von (0x5c) ist dort zufällig auch in einigen anderen Zeichen enthalten (wie α :0xa3 0x5c und die UTF-8-Kodierung von endet zufällig auf 0xa3).

Verwandte:PIC16F877 analoge Pin-Konfiguration?

Erwarten Sie auf keinen Fall Dinge wie

perl -Mopen=locale -Mutf8 -pe 'y/Á-Ź/A-Z/'

daran arbeiten, akute Akzente zu entfernen. Das Obige ist eigentlich nur

perl -Mopen=locale -Mutf8 -pe 'y/x{c1}-x{179}/x{41}-x{5a}/'

Das heißt, der Bereich basiert auf den Unicode-Codepoints. Daher sind Bereiche außerhalb sehr gut definierter Sequenzen, die zufällig „richtig sind, nicht nützlich ” Reihenfolge in Unicode wie A-Z , 0-9 .

Wenn Sie akute Akzente entfernen möchten, müssen Sie fortgeschrittenere Tools verwenden wie:

perl -Mopen=locale -MUnicode::Normalize -pe '
  $_ = NFKD($_); s/x{301}//g; $_ = NFKC($_)'

Das heißt, verwenden Sie Unicode-Normalisierungsformen, um Zeichen zu zerlegen, entfernen Sie die Akut-Akzente (hier die Kombinationsform U+0301 ) und neu zusammensetzen.

Ein weiteres nützliches Werkzeug zum Transliterieren von Unicode ist uconv von der Intensivstation. Obiges könnte zum Beispiel auch geschrieben werden als:

uconv -x '::NFKD; u0301>; ::NFKC;'

Würde aber nur mit UTF-8-Daten funktionieren. Sie benötigen:

iconv -t utf-8 | uconv -x '::NFKD; u0301>; ::NFKC;' | iconv -f utf-8

Um Daten im Gebietsschema des Benutzers verarbeiten zu können.


Linux
  1. Wofür stehen Sonderzeichen in Echo {a..z}?

  2. Entferne unbekannte Zeichen aus Zeichenfolge für -exec?

  3. Passwort mit Sonderzeichen zur Verwendung mit Expect-Skript konvertieren?

  4. Warum transliteriert wprintf russischen Text in Unicode unter Linux in Latein?

  5. Was könnte seltsame Zeichen in Vim verursachen?

4 Linux-Distributionen für Spiele

Eine Einführung in bpftrace für Linux

Auswählen eines Druckers für Linux

Bash für Schleife

Abrufen der Zeichen  und â in der Linux PuTTY-Konsole

Zeigen Sie Unicode-Codepunkte für alle Buchstaben in der Datei auf Bash an