GNU/Linux >> Belajar Linux >  >> Linux

Linux – Bagaimana Membuat TR Mengetahui Karakter Non-ascii(unicode)?

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

Linux
  1. Cara membuat komputer lama menjadi berguna kembali

  2. Bagaimana cara membuat paket pengujian Travis CI untuk Linux, OS X, Windows?

  3. Bagaimana cara mengetik karakter khusus di Linux?

  1. Linux – Bagaimana Membuat Proses Tidak Terlihat oleh Pengguna Lain?

  2. Cara memastikan aplikasi tetap berjalan di Linux

  3. Bagaimana cara membuat cadangan diferensial di linux?

  1. Bagaimana membuat KDE terlihat seperti GNOME di Linux

  2. Bagaimana cara menulis karakter non-ASCII menggunakan gema?

  3. Dua versi python di linux. bagaimana menjadikan 2.7 sebagai default