GNU/Linux >> Belajar Linux >  >> Linux

Tr Analog Untuk Karakter Unicode?

Saya membutuhkan utilitas internasional yang melakukan hal yang sama seperti tr :mendapatkan karakter dari aliran dan menggantinya dengan karakter yang sesuai.
Bukan solusi kasus khusus seperti yang lebih rendah ke atas, tetapi solusi kasus umum diperlukan.
Tanpa gorillion piped sed telepon jika memungkinkan.

Perhatikan bahwa tr tidak bekerja di Linux:menerjemahkan byte, bukan karakter. Ini gagal dengan pengkodean multibyte.

$ tr --version | head -n 1
tr (GNU coreutils) 8.23
$ echo $LC_CTYPE
en_US.UTF-8
$ echo 'Ångstrom' | tr Æ Œ         
Ņngstrom

Jawaban yang Diterima:

GNU sed bekerja dengan karakter multi-byte. Jadi:

$ echo é½Æ | sed 'y/é½Æ/ABŒ/'
ABŒ

Bukannya GNU tr belum diinternasionalkan tetapi tidak mendukung karakter multi-byte (seperti yang non-ASCII di lokal UTF-8). GNU tr akan bekerja dengan Æ , Œ selama mereka byte tunggal seperti di set karakter iso8859-15.

Lebih lanjut tentang itu di Bagaimana membuat tr mengetahui karakter non-ascii(unicode)?

Bagaimanapun, itu tidak ada hubungannya dengan Linux, ini tentang tr implementasi pada sistem. Apakah sistem itu menggunakan Linux sebagai kernel atau tr dibuat untuk Linux atau menggunakan API kernel Linux tidak relevan karena bagian dari tr fungsionalitas terjadi di ruang pengguna.

busybox tr dan GNU tr adalah yang paling umum ditemukan pada distribusi perangkat lunak yang dibuat untuk Linux dan tidak mendukung karakter multi-byte, tetapi ada yang lain yang telah di-porting ke Linux seperti tr dari heirloom toolchest (porting dari OpenSolaris) atau ast-open yang melakukannya.

Perhatikan bahwa sed y tidak mendukung rentang seperti a-z . Perhatikan juga bahwa jika skrip yang berisi sed 'y/é½Æ/ABŒ/' ditulis dalam rangkaian karakter UTF-8, ia tidak akan berfungsi lagi seperti yang diharapkan jika dipanggil di lokal di mana UTF-8 bukan rangkaian karakter.

Alternatifnya bisa menggunakan perl :

perl -Mopen=locale -Mutf8 -pe 'y/a-zé½Æ/A-ZABŒ/'

Di atas, kode perl diharapkan dalam UTF-8, tetapi akan memproses input dalam pengkodean lokal (dan output dalam pengkodean yang sama). Jika dipanggil dalam lokal UTF-8, itu akan mentransliterasi Æ . UTF-8 (0xc3 0x86) ke Œ U UTF-8 (0xc5 0x92) dan dalam ISO8859-15 sama tetapi untuk 0xc6 -> 0xbc.

Di sebagian besar shell, memiliki karakter UTF-8 di dalam tanda kutip tunggal harus OK bahkan jika skrip dipanggil di lokal di mana UTF-8 bukan charset (pengecualian adalah yash yang akan mengeluh jika byte tersebut tidak membentuk karakter yang valid di lokal). Namun, jika Anda menggunakan kutipan selain kutipan tunggal, hal itu dapat menyebabkan masalah. Misalnya,

perl -Mopen=locale -Mutf8 -pe "y/♣`/&'/"

akan gagal di lokal di mana charset adalah BIG5-HKSCS karena penyandian Œ (0x5c) kebetulan juga terdapat di beberapa karakter lain di sana (seperti α :0xa3 0x5c, dan pengkodean UTF-8 dari kebetulan berakhir dengan 0xa3).

Terkait:konfigurasi pin analog PIC16F877?

Bagaimanapun, jangan mengharapkan hal-hal seperti

perl -Mopen=locale -Mutf8 -pe 'y/Á-Ź/A-Z/'

untuk bekerja menghilangkan aksen akut. Di atas sebenarnya hanya

perl -Mopen=locale -Mutf8 -pe 'y/x{c1}-x{179}/x{41}-x{5a}/'

Artinya, rentang didasarkan pada titik kode unicode. Jadi rentang tidak akan berguna di luar urutan yang didefinisikan dengan sangat baik yang kebetulan berada di “kanan ” pesan dalam Unicode seperti A-Z , 0-9 .

Jika Anda ingin menghilangkan aksen yang tajam, Anda harus menggunakan alat yang lebih canggih seperti:

perl -Mopen=locale -MUnicode::Normalize -pe '
  $_ = NFKD($_); s/x{301}//g; $_ = NFKC($_)'

Yaitu menggunakan bentuk normalisasi Unicode untuk menguraikan karakter, menghilangkan aksen akut (di sini bentuk gabungan U+0301 ) dan komposisi ulang.

Alat lain yang berguna untuk mentransliterasi Unicode adalah uconv dari ICU. Misalnya, di atas juga dapat ditulis sebagai:

uconv -x '::NFKD; u0301>; ::NFKC;'

Padahal hanya akan bekerja pada data UTF-8. Anda membutuhkan:

iconv -t utf-8 | uconv -x '::NFKD; u0301>; ::NFKC;' | iconv -f utf-8

Untuk dapat memproses data di lokal pengguna.


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

  2. Apa Arti Karakter Khusus Dalam Echo {a..z}?

  3. Keluar dari Karakter Tidak Dikenal Dari String Untuk -exec?

  1. Konversi Kata Sandi Dengan Karakter Khusus Untuk Digunakan Dengan Script Harapkan?

  2. Cara mengonversi \uXXXX unicode ke UTF-8 menggunakan alat konsol di *nix

  3. Mengapa wprintf mentransliterasi teks Rusia di Unicode ke bahasa Latin di Linux?

  1. Bagaimana Cara Memindai Karakter Tidak Valid Di Gedit?

  2. Apakah ada yang setara dengan cd - untuk cp atau mv?

  3. Bersarang untuk loop