Как указать символы, используя шестнадцатеричные коды в `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> 
    ...

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

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

Я использую Ubuntu 10.04


1
Что вы имеете в виду "не работает"? Также -vинвертирует совпадение, из текста вашего вопроса кажется, что это не то, что вы хотите.
Christian.K

@ Christian.K Извините за задержку ... Я отредактировал вопрос, пожалуйста, посмотрите.

Я все еще жду соответствующего ответа. :(
Друбо Бхаттачарджи

Ответы:


21

Посмотри на этот вопрос .

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

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

а также

grep '[अ-व]'

эквивалентны, и они выполняют сопоставление на основе локали (то есть сопоставление зависит от правил сортировки сценария devanagari (то есть сопоставление НЕ "любой символ между \ u0905 и \ 0935", а вместо этого "что-либо сортирующее между devanagari А и деванагари В.А. "; возможны различия.

С другой стороны, у вас есть это (примечание -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
энзотиб

Действительно, OP дал значения Unicode, а не шестнадцатеричные дампы в кодировке UTF-8: - / Так grepкак он не связан с какой-либо библиотекой, я думаю, что преобразование диапазона не может быть выполнено grep: - /
Stéphane Gimenez

1
Кстати, zshможет интерпретировать "\u0900"и "\u097F", но поведение будет зависеть от непрерывности кодированного диапазона UTF-8 (вероятно, так оно и есть).
Стефан Гименес

Нет grep -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> .... Это не ожидается. :(, Могу ли я использовать юникод вместо шестнадцатеричного кода или набора символов ('अ-व')?
Друбо Бхаттачарджи

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

заставляет grep "видеть" персонажа, который вам нужен.
Чтобы понять строку выше, вы можете использовать echo:

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

Затем мы можем построить диапазон символов, как вы просите:

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

Это ответ на ваш вопрос:

Как я могу использовать шестнадцатеричный код вместо अ и व?


Это, безусловно, лучший ответ - он четко решает проблему представления точек Unicode в оболочке и показывает, как перемещаться между ними шестнадцатеричными кодами.
Стефано

2

мы хотели преобразовать открытые двойные кавычки без ascii и двойные кавычки в обычные двойные кавычки ("). Также одинарные кавычки без ascii в обычные одинарные кавычки (')

чтобы увидеть их в файле (оболочка Ubuntu Bash):

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