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

Linux – Wie macht man Tr auf Nicht-ASCII-Zeichen (Unicode) aufmerksam?

Ich versuche, einige Zeichen aus der Datei (UTF-8) zu entfernen. Ich verwende tr dazu:

tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat 

Die Datei enthält einige fremde Zeichen (wie „Латвийская“ oder „àé“). tr scheint sie nicht zu verstehen:Es behandelt sie als Nicht-Alpha und entfernt sie auch.

Ich habe versucht, einige meiner Gebietsschemaeinstellungen zu ändern:

LC_CTYPE=C LC_COLLATE=C tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat
LC_CTYPE=ru_RU.UTF-8 LC_COLLATE=C tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat
LC_CTYPE=ru_RU.UTF-8 LC_COLLATE=ru_RU.UTF-8 tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat

Leider hat nichts davon funktioniert.

Wie kann ich tr machen verstehst du Unicode?

Akzeptierte Antwort:

Das ist eine bekannte (1, 2, 3, 4, 5, 6) Einschränkung der GNU-Implementierung von tr .

Es ist nicht so sehr, dass es Fremd nicht unterstützt , nicht-englische oder Nicht-ASCII-Zeichen, unterstützt aber keine Multibyte-Zeichen.

Diese kyrillischen Zeichen würden in Ordnung behandelt, wenn sie im Zeichensatz iso8859-5 (Einzelbyte pro Zeichen) geschrieben wären (und Ihr Gebietsschema diesen Zeichensatz verwendet hat), aber Ihr Problem ist, dass Sie UTF-8 verwenden, wo es kein ASCII ist Zeichen werden in 2 oder mehr Bytes kodiert.

GNU hat einen Plan (siehe auch), um das zu beheben, und die Arbeit ist im Gange, aber noch nicht so weit.

FreeBSD oder Solaris tr habe das Problem nicht.

In der Zwischenzeit für die meisten Anwendungsfälle von tr , können Sie GNU sed oder GNU awk verwenden, die Multibyte-Zeichen unterstützen.

Zum Beispiel Ihr:

tr -cs '[[:alpha:][:space:]]' ' '

könnte geschrieben werden:

gsed -E 's/( |[^[:space:][:alpha:]])+/ /'

oder:

gawk -v RS='( |[^[:space:][:alpha:]])+' '{printf "%s", sep $0; sep=" "}'

Um zwischen Klein- und Großbuchstaben umzuwandeln (tr '[:upper:]' '[:lower:]' ):

gsed 's/[[:upper:]]/l&/g'

(das l ist ein kleiner L , nicht die 1 Ziffer).

oder:

gawk '{print tolower($0)}'

Für die Portabilität perl ist eine weitere Alternative:

perl -Mopen=locale -pe 's/([^[:space:][:alpha:]]| )+/ /g'
perl -Mopen=locale -pe '$_=lc$_'

Wenn Sie wissen, dass die Daten in einem Einzelbyte-Zeichensatz dargestellt werden können, können Sie sie in diesem Zeichensatz verarbeiten:

(export LC_ALL=ru_RU.iso88595
 iconv -f utf-8 |
   tr -cs '[:alpha:][:space:]' ' ' |
   iconv -t utf-8) < Russian-file.utf8

Linux
  1. Wie man einen alten Computer wieder brauchbar macht

  2. Linux – Wie kann man einen Prozess für andere Benutzer unsichtbar machen?

  3. So stellen Sie sicher, dass eine Anwendung unter Linux weiterhin ausgeführt wird

  4. Wie schreibe ich Nicht-ASCII-Zeichen mit Echo?

  5. Wie erstelle ich ein Travis CI-Testpaket für Linux, OS X, Windows?

Wie man eine Datei unter Linux ausführbar macht

So erstellen Sie einen Multiboot-USB in Linux und Windows

Wie Linux Ihr Leben einfacher machen kann

So entfernen Sie (^M) Zeichen aus einer Datei in Linux

Wie mache ich eine Datei im Linux-Terminal ausführbar?

So erstellen Sie Minecraft Server auf Linux-Distributionen