Wie konvertiere ich UTF-8-TXT-Dateien in Großbuchstaben in Bash?

10

Ich habe einige UTF-8 .txt-Dateien, die ich in Großbuchstaben konvertieren möchte. Wenn es nur ASCII wäre, könnte ich verwenden:

tr [:lower:] [:upper:]

Aber da ich mit Diakritika und anderen Dingen arbeite, scheint es nicht zu funktionieren. Ich denke, es könnte funktionieren, wenn ich das entsprechende Gebietsschema festlege, aber ich brauche dieses Skript, um portabel zu sein.

VPeric
quelle

Antworten:

14

Alle:

tr '[:lower:]' '[:upper:]'

(vergessen Sie nicht die Anführungszeichen, sonst das wird nicht funktionieren , wenn es eine Datei mit dem Namen :, l... oder rim aktuellen Verzeichnis) oder:

awk '{print toupper($0)}'

oder:

dd conv=ucase

sollen Zeichen gemäß den im aktuellen Gebietsschema definierten Regeln in Großbuchstaben umwandeln. Selbst wenn Gebietsschemas UTF-8 als Zeichensatz verwenden und die Konvertierung von Klein- in Großbuchstaben klar definieren, folgen ihnen zumindest GNU dd, GNU trund mawk( awkzum Beispiel die Standardeinstellung unter Ubuntu) nicht. Es gibt auch keine Standardmethode zum Festlegen anderer Gebietsschemas als Coder POSIX. Wenn Sie also UTF-8-Dateien unabhängig vom aktuellen Gebietsschema portabel in Großbuchstaben konvertieren möchten, haben Sie mit der Standard-Toolchest kein Glück.

Aus Gründen der Portabilität ist Perl die beste Wahl:

$ echo lľsšcčtťzž | PERLIO=:utf8 perl -pe '$_=uc'
LĽSŠCČTŤZŽ

Nun müssen Sie aufpassen, dass sich nicht alle darüber einig sind, wie die Großbuchstabenversion eines bestimmten Charakters lautet.

In türkischen Gebietsschemas ist der Großbuchstabe ibeispielsweise nicht I, sondern İ( <U0130>). Hier mit der Erbstück-Werkzeugkiste transtelle von GNU tr:

$ echo ií | LC_ALL=C.UTF-8 tr '[:lower:]' '[:upper:]'
IÍ
$ echo ií | LC_ALL=tr_TR.UTF-8 tr '[:lower:]' '[:upper:]'
İÍ

Auf meinem System ist die perlKonvertierung nach oben in definiert /usr/share/perl/5.14/unicore/To/Upper.pl, und ich stelle fest, dass sie sich beispielsweise bei einigen Zeichen aus der GNU-Bibliothek toupper()im C.UTF8Gebietsschema anders verhält und perlgenauer ist. Zum Beispiel perlkonvertiert ɀ korrekt in Ɀ , die GNU libc (2.17) nicht.

Stéphane Chazelas
quelle
Für was es wert ist, arbeite ich mit tschechischen Buchstaben (und das Beispiel, das Sie verwendet haben, ist eigentlich slowakisch), wobei alle Großbuchstaben klar definiert sind, aber das Gebietsschema wahrscheinlich C und nicht Tschechisch ist, also ist das ein Problem. Perl wird bereits in dieser Toolchain verwendet, daher ist das Hinzufügen einer weiteren Verwendung möglicherweise nicht schlecht. Danke übrigens für die ausführliche Erklärung!
VPeric
3

Ich denke, Sie können dies mit awkund seiner toupperFunktion tun .

Beispielsweise

Funktioniert nicht mit GNU tr:

$ echo lľsšcčtťzž | tr '[:lower:]' '[:upper:]'
LľSšCčTťZž

Funktioniert mit GNU awk:

$ echo lľsšcčtťzž | awk '{ print toupper($0) }'
LĽSŠCČTŤZŽ
slm
quelle
@StephaneChazelas - danke, ich habe das fehlerhafte Beispiel geändert.
slm
Das hängt von den aktuellen Locale und auf der troder awkUmsetzung. Beispielsweise trkonvertieren die meisten Zeichen korrekt, wenn sie sich in einem UTF8-Gebietsschema befinden. Dies entspricht dem aktuellen Gebietsschema, GNU trjedoch nicht. mawknicht.
Stéphane Chazelas
1
Bei FreeBSD (9.1) ist es umgekehrt. Es funktioniert mit tr, aber nicht mitawk
Stéphane Chazelas
@StephaneChazelas - Ich bin nicht so vertraut mit den Abweichungen 8-). Jemand, der gerade herabgestimmt hat, fragt sich warum?
slm
2

Dies funktioniert mit OS X, traber nicht mit GNU tr:

tr '[:lower:]' '[:upper:]'

Dies funktioniert mit, gawkaber nicht mit mawkoder nawk(was /usr/bin/awkin OS X ist):

awk '{print toupper($0)}'

Eine andere Option ist die Verwendung von GNU sed:

sed 's/./\u&/g'

In Bash 4.0 und höher können Sie auch die ^^Parametererweiterung verwenden:

while IFS= read -r l;do printf %s\\n "${l^^}";done
Nisetama
quelle