Як вказати символи за допомогою шістнадцяткових кодів у `grep`?


27

Я використовую наступну команду для позначення діапазону набору символів для шістнадцяткового коду 0900 (замість अ) до 097F (замість व). Як я можу використовувати шістнадцятковий код замість अ і व?

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

Я отримую такий вихід:

    <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> 
    ...

Я просто хочу використовувати шістнадцятковий код замість अ і व у наведеній вище команді.

Якщо використання шістнадцяткового коду взагалі не можливе, чи можу я використовувати Unicode замість шістнадцяткового коду для набору символів ('अ-व')?

Я використовую Ubuntu 10.04


1
Що означає «не працює»? Також -vперевертає відповідність, з тексту запитання виходить, що це не те, що ви хочете.
Крістіан.К

@ Christian.K Вибачте за затримку ... Я змінив питання, будь ласка, подивіться.

Я все ще чекаю відповідної відповіді. :(
Dhrubo Bhattacharjee

Відповіді:


21

Подивіться на це питання .

Текст зазвичай кодується в UTF-8; тож вам доведеться використовувати шістнадцяткові значення байтів, які використовуються при кодуванні utf-8.

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

і

grep '[अ-व]'

еквівалентні, і вони виконують узгодження локалі на основі (тобто, узгодження залежить від сортувальних правил деванагари (тобто, що співпадає НЕ «будь-який символ між \ u0905 і \ 0935» , але замість того, щоб «нічого сортуванням між деванагари A і devanagari VA "; можуть бути відмінності.

З іншого боку, у вас є це (примітка -P):

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

що дозволить виконати бінарне зіставлення з тими значеннями байтів .


2
Поясніть, будь ласка, префікс "["$'та суфікс"]"
Джонатан Комар

6

Якщо уникнення оболонки достатньо, ви можете використовувати такий $'\xHH'синтаксис:

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

Чи достатньо цього для вашого випадку використання?


echo 'अ-व' | hdдарує меніe0 a4 85 - e0 a4 b5
enzotib

Дійсно, ОП дав значення унікоду, а не шістнадцятковий скид у кодуванні UTF-8: - / Оскільки grepне пов'язаний з жодною lib, я думаю, що неможливо, щоб конверсія діапазону виконувалась grep: - /
Stéphane Gimenez

1
Btw, zshздатний інтерпретувати "\u0900"і "\u097F", але поведінка буде покладатися на те, що закодований діапазон UTF-8 є безперервним (можливо, це і є).
Стефан Гіменез

Ні греп -v "<[" $ '\ x09 \ x00' "-" $ '\ x09 \ x7F' "] * \ s" дає наступний вихід <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> .... Цього не очікується. :(, Чи можу я використовувати Unicode замість шістнадцяткового коду чи набору символів ('अ-व')?
Dhrubo Bhattacharjee,

6

Значення "шістнадцятковий", яке 0x0900ви написали, - це саме значення кодової точки UNICODE, яка також знаходиться у шістнадцятковій кількості.

шістнадцятковий код 0900 (замість अ)

Я вважаю , що то , що ви хочете сказати , є шестнадцатеричной точкою UNICODE коду: U0905.

Характер у U-0900 не один ви використовували: .
Цей символ є U0905 , що є частиною цієї сторінки Unicode або перерахований на цій сторінці .

У bash(встановлений за замовчуванням в Ubuntu) або безпосередньо з програмою за адресою: /usr/bin/printf(але не з shprintf), символ Unicode може бути створений із:

$ printf '\u0905'

$ /usr/bin/printf '\u0905'

Однак цей символ, що походить від номера кодової точки, може бути представлений кількома потоками байтів, залежно від того, яка сторінка коду використовується.
Повинно бути очевидним, що \U0905це 0x09 0x05в UTF-16 (UCS-2 тощо)
та 0x00 0x00 0x09 0x05в UTF-32.
Це може бути не очевидно, але в utf-8 воно представлено 0xe0 0xa4 0x85:

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

Якщо локаль консолі чимось схожий на en_US.UTF-8.

І я кажу про оболонку, тому що саме вона перетворює рядок у те, що отримує додаток. Це:

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

змушує греп "бачити" потрібного вам персонажа.
Щоб зрозуміти рядок вище, ви можете скористатися echo:

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

Тоді ми можемо побудувати діапазон символів за вашим запитом:

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

Це відповідає на ваше запитання:

Як я можу використовувати шістнадцятковий код замість अ і व?


Це, безумовно, найкраща відповідь - це чітко вирішує питання представлень унікодних точок в оболонці та показує, як повертатися між ними шістнадцятковими кодами
стефано

2

ми хотіли перетворити подвійну цитату non-ascii та закрити подвійну цитату у звичайні подвійні лапки (").

щоб побачити їх у файлі (оболонка bash ubuntu):

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

перекладіть їх:

$ /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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.