Saya mencoba menghapus beberapa karakter dari file (UTF-8). Saya menggunakan tr
untuk tujuan ini:
tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat
File berisi beberapa karakter asing (seperti “Латвийская” atau “é”). tr
tampaknya tidak memahaminya:ia memperlakukannya sebagai non-alfa dan juga menghapusnya.
Saya telah mencoba mengubah beberapa pengaturan lokal saya:
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
Sayangnya, tidak ada yang berhasil.
Bagaimana saya bisa membuat tr
mengerti Unicode?
Jawaban yang Diterima:
Itu adalah batasan (1, 2, 3, 4, 5, 6) yang diketahui dari implementasi GNU dari tr
.
Bukan berarti tidak mendukung asing , karakter non-Inggris atau non-ASCII, tetapi tidak mendukung karakter multi-byte.
Karakter Cyrillic tersebut akan diperlakukan OK, jika ditulis dalam set karakter iso8859-5 (byte tunggal per karakter) (dan lokal Anda menggunakan rangkaian karakter itu), tetapi masalah Anda adalah Anda menggunakan UTF-8 di mana non-ASCII karakter dikodekan dalam 2 byte atau lebih.
GNU punya rencana (lihat juga) untuk memperbaikinya dan pekerjaan sedang berjalan tetapi belum sampai.
FreeBSD atau Solaris tr
tidak masalah.
Sementara itu, untuk sebagian besar kasus penggunaan tr
, Anda dapat menggunakan GNU sed atau GNU awk yang mendukung karakter multi-byte.
Misalnya, Anda:
tr -cs '[[:alpha:][:space:]]' ' '
dapat ditulis:
gsed -E 's/( |[^[:space:][:alpha:]])+/ /'
atau:
gawk -v RS='( |[^[:space:][:alpha:]])+' '{printf "%s", sep $0; sep=" "}'
Untuk mengonversi antara huruf kecil dan huruf besar (tr '[:upper:]' '[:lower:]'
):
gsed 's/[[:upper:]]/l&/g'
(itu l
adalah huruf kecil L
, bukan 1
angka).
atau:
gawk '{print tolower($0)}'
Untuk portabilitas, perl
adalah alternatif lain:
perl -Mopen=locale -pe 's/([^[:space:][:alpha:]]| )+/ /g'
perl -Mopen=locale -pe '$_=lc$_'
Jika Anda mengetahui bahwa data dapat direpresentasikan dalam kumpulan karakter byte tunggal, maka Anda dapat memprosesnya dalam rangkaian karakter tersebut:
(export LC_ALL=ru_RU.iso88595
iconv -f utf-8 |
tr -cs '[:alpha:][:space:]' ' ' |
iconv -t utf-8) < Russian-file.utf8