Bagaimana cara mengubah file txt UTF-8 ke semua huruf besar dalam bash?

10

Saya memiliki beberapa file .txt UTF-8 yang ingin saya konversi ke semua huruf besar. Jika itu hanya ASCII, saya bisa menggunakan:

tr [:lower:] [:upper:]

Tetapi karena saya bekerja dengan diakritik dan semacamnya, sepertinya tidak berhasil. Saya kira itu mungkin berhasil jika saya mengatur lokal yang sesuai, tetapi saya perlu skrip ini agar portabel.

VPeric
sumber

Jawaban:

14

Semua:

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

(jangan lupa tanda kutip, sebaliknya yang tidak akan bekerja jika ada file yang bernama :, l, ... atau rdi direktori saat ini) atau:

awk '{print toupper($0)}'

atau:

dd conv=ucase

dimaksudkan untuk mengonversi karakter menjadi huruf besar sesuai dengan aturan yang ditentukan dalam lokal saat ini. Namun, bahkan ketika lokal menggunakan UTF-8 sebagai set karakter dan dengan jelas mendefinisikan konversi dari huruf kecil ke huruf besar, setidaknya GNU dd, GNU trdan mawk(default awkpada Ubuntu misalnya) tidak mengikuti mereka. Juga, tidak ada cara standar untuk menentukan lokal selain Catau POSIX, jadi jika Anda ingin mengonversi file UTF-8 menjadi huruf besar dengan mudah terlepas dari lokal saat ini, Anda kurang beruntung dengan toolchest standar.

Seperti sering, untuk portabilitas, taruhan terbaik Anda mungkin perl:

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

Sekarang, Anda perlu berhati-hati bahwa tidak semua orang setuju dengan versi huruf besar dari karakter tertentu.

Misalnya, di lokal Turki, huruf besar ibukan I, tapi İ( <U0130>). Di sini dengan toolchest heirloom, trbukan GNU tr:

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

Pada sistem saya, perlkonversi ke atas didefinisikan dalam /usr/share/perl/5.14/unicore/To/Upper.pl, dan saya menemukan bahwa ia berperilaku berbeda pada beberapa karakter dari libc GNU toupper()di C.UTF8lokal misalnya, perlmenjadi lebih akurat. Misalnya perldengan benar mengkonversi ɀ ke Ɀ , libc GNU (2.17) tidak.

Stéphane Chazelas
sumber
Untuk apa nilainya, saya bekerja dengan huruf-huruf Ceko (dan contoh yang Anda gunakan sebenarnya adalah bahasa Slowakia), di mana semua huruf besar didefinisikan dengan jelas, tetapi set lokal mungkin akan menjadi C dan bukan Ceko sehingga itu menjadi masalah. Perl sudah digunakan dalam rantai alat ini, jadi menambahkan penggunaan lain mungkin tidak terlalu buruk. Terima kasih atas penjelasan terperinci, btw!
VPeric
3

Saya pikir Anda bisa melakukan ini dengan awkdan toupperfungsinya.

Sebagai contoh

Tidak bekerja dengan GNU tr:

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

Bekerja dengan GNU awk:

$ echo lľsšcčtťzž | awk '{ print toupper($0) }'
LĽSŠCČTŤZŽ
slm
sumber
@StephaneChazelas - terima kasih saya mengubah contoh yang gagal.
slm
Itu tergantung pada lokal saat ini dan pada tratau awkimplementasi. Sebagai contoh, sebagian besar trakan mengkonversi karakter dengan benar ketika di lokal UTF8, menurut lokal saat ini, GNU trtidak. mawktidak.
Stéphane Chazelas
1
Sebenarnya, di FreeBSD (9.1), ini sebaliknya. Ini bekerja dengan tr, tetapi tidak denganawk
Stéphane Chazelas
@StephaneChazelas - Saya tidak berpengalaman dengan varian 8-). Seseorang baru saja kalah, mengapa?
slm
2

Ini berfungsi dengan OS X trtetapi tidak dengan GNU tr:

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

Ini berfungsi dengan gawktetapi tidak dengan mawkatau nawk(yang ada /usr/bin/awkdi OS X):

awk '{print toupper($0)}'

Pilihan lain adalah menggunakan GNU sed:

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

Di Bash 4.0 dan yang lebih baru, Anda juga dapat menggunakan ^^ekspansi parameter:

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