Bagaimana cara menentukan karakter menggunakan kode heksadesimal di `grep`?

27

Saya menggunakan perintah berikut untuk grep rentang set karakter untuk kode heksadesimal 0900 (bukan अ) ke 097F (bukan व). Bagaimana saya bisa menggunakan kode heksadesimal sebagai ganti अ dan व?

bzcat archive.bz2 | grep -v '<[अ-व]*\s' | tr '[:punct:][:blank:][:digit:]' '\n' | uniq | grep -o '^[अ-व]*$' | sort -f | uniq -c | sort -nr | head -50000 | awk '{print "<w f=\""$1"\">"$2"</w>"}' > hindi.xml

Saya mendapatkan output berikut:

    <w f="399651">और</w>
    <w f="264423">एक</w>
    <w f="213707">पर</w>
    <w f="74728">कर</w>
    <w f="44281">तक</w>
    <w f="35125">कई</w>
    <w f="26628">द</w>
    <w f="23981">इन</w>
    <w f="22861">जब</w> 
    ...

Saya hanya ingin menggunakan kode heksadesimal alih-alih अ dan व pada perintah di atas.

Jika menggunakan kode heksadesimal sama sekali tidak memungkinkan, dapatkah saya menggunakan unicode alih-alih kode heksadesimal untuk rangkaian karakter ('अ-व')?

Saya menggunakan Ubuntu 10,04

Dhrubo Bhattacharjee
sumber
1
Apa maksudmu "tidak bekerja"? Juga -vmembalikkan kecocokan, dari teks pertanyaan Anda sepertinya bukan itu yang Anda inginkan.
Christian.K
@ Christian.K Maaf atas keterlambatan ... Saya telah mengedit pertanyaan, silakan lihat.
Saya masih menunggu jawaban yang tepat. :(
Dhrubo Bhattacharjee

Jawaban:

21

Lihatlah pertanyaan ini .

Teks biasanya dikodekan dalam UTF-8; jadi Anda harus menggunakan hex hex byte yang digunakan dalam utf-8 encoding.

grep "["$'\xe0\xa4\x85'"-"$'\xe0\xa4\xb5'"]"

dan

grep '[अ-व]'

adalah setara, dan mereka melakukan pencocokan berbasis lokal (yaitu, pencocokan bergantung pada aturan penyortiran skrip devanagari (yaitu, pencocokan TIDAK "karakter apa pun antara \ u0905 dan \ 0935" melainkan "penyortiran apa pun antara devanagari A dan devanagari VA "; mungkin ada perbedaan.

Di sisi lain, Anda memiliki ini (catatan-P):

grep -P "\xe0\xa4[\x85-\xb5]"

yang akan melakukan pencocokan biner dengan nilai-nilai byte tersebut .

Pablo Saratxaga
sumber
2
Tolong jelaskan awalan "["$'dan sufiks"]"
Jonathan Komar
6

Jika shell melarikan diri sudah cukup Anda dapat menggunakan $'\xHH'sintaksis seperti ini:

grep -v "<["$'\x09\x00'"-"$'\x09\x7F'"]*\s"

Apakah itu cukup untuk kasus penggunaan Anda?

Stéphane Gimenez
sumber
echo 'अ-व' | hdmemberi sayae0 a4 85 - e0 a4 b5
enzotib
Memang OP memberikan nilai unicode, bukan dump heksadesimal dalam pengkodean UTF-8: - / Karena greptidak terhubung dengan lib, saya kira itu tidak mungkin untuk memiliki rentang konversi dilakukan oleh grep: - /
Stéphane Gimenez
1
Btw, zshmampu menafsirkan "\u0900"dan "\u097F", tetapi perilaku akan bergantung pada rentang UTF-8 yang dikodekan terus menerus (mungkin itu).
Stéphane Gimenez
Tidak ada grep -v "<[" $ '\ x09 \ x00' "-" $ '\ x09 \ x7F' "] * \ s" memberikan output berikut <wf = "16929"> x </w> <wf = " 10995 "> F </w> <wf =" 2548 "> FF </w> <wf =" 762 "> FFFFFF </w> <wf =" 655 "> FFFF </w> <wf =" 266 " > xx </w> <wf = "215"> FFF </w> <wf = "117"> xxx </w> .... Ini tidak diharapkan. :(, Dapatkah saya menggunakan unicode alih-alih kode heksadesimal atau rangkaian karakter ('अ-व')?
Dhrubo Bhattacharjee
6

Nilai "heksadesimal" yang 0x0900Anda tulis persis dengan nilai titik kode UNICODE yang juga dalam heksadesimal.

kode heksadesimal 0900 (bukan अ)

Saya percaya bahwa apa yang Anda bermaksud mengatakan adalah heksadesimal titik kode UNICODE: U0905.

Karakter di U-0900 adalah bukan yang Anda digunakan: .
Karakter itu adalah U0905 , bagian dari halaman Unicode ini , atau terdaftar di halaman ini .

Dalam bash(diinstal secara default di Ubuntu), atau langsung dengan program di: /usr/bin/printf(tetapi tidak dengan shprintf), karakter Unicode dapat dihasilkan dengan:

$ printf '\u0905'

$ /usr/bin/printf '\u0905'

Namun, karakter itu, yang berasal dari nomor titik kode dapat diwakili oleh beberapa aliran byte tergantung halaman kode mana yang digunakan.
Seharusnya jelas \U0905ada 0x09 0x05di UTF-16 (UCS-2, dll)
dan 0x00 0x00 0x09 0x05di UTF-32.
Mungkin tidak jelas tetapi dalam utf-8 diwakili oleh 0xe0 0xa4 0x85:

$ /usr/bin/printf '\u0905' | od -vAn -tx1
e0 a4 85

Jika lokal konsol Anda mirip dengan en_US.UTF-8.

Dan saya berbicara tentang shell karena shell yang mengubah string menjadi apa yang diterima aplikasi. Ini:

grep "$(printf '\u0905')" file

membuat grep "melihat" karakter yang Anda butuhkan.
Untuk memahami baris di atas, Anda dapat menggunakan gema:

$ echo grep "$(printf '\u0905')" file
grep  file

Kemudian, kita dapat membangun rentang karakter, seperti yang Anda minta:

$ echo grep "$(printf '[\u0905-\u097f]')" file
grep [अ-ॿ] file

Itu menjawab pertanyaan Anda:

Bagaimana saya bisa menggunakan kode heksadesimal sebagai ganti अ dan व?

sorontar
sumber
Sejauh ini, inilah jawaban terbaik --- ini dengan jelas membahas masalah representasi unicode points dalam shell dan menunjukkan bagaimana bolak-balik di antara mereka hex code.
stefano
2

kami ingin mengonversikan kuotasi terbuka non-ascii dan menutup kuotasi ganda menjadi kuotasi ganda reguler ("). Juga kuotasi tunggal non-ascii menjadi kuota tunggal reguler (').

untuk melihatnya di file (ubuntu bash shell):

$ grep -P "\x92" infile.txt  (single)
$ grep -P "\x93" infile.txt  (open double)
$ grep -P "\x94" infile.txt  (close double)

terjemahkan mereka:

$ /bin/sed "s/\x92/'/g" a.txt > b.txt
$ /bin/sed 's/\x93/"/g' b.txt > c.txt
$ /bin/sed 's/\x94/"/g' c.txt > d.txt
Gayus Gracchus
sumber