Jak określić znaki za pomocą kodów szesnastkowych w `grep`?


27

Używam następującego polecenia do grep zakresu zestawu znaków dla kodu szesnastkowego 0900 (zamiast अ) do 097F (zamiast व). Jak mogę użyć kodu szesnastkowego zamiast अ i व?

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

Otrzymuję następujące dane wyjściowe:

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

Chcę tylko użyć kodu szesnastkowego zamiast अ i व w powyższym poleceniu.

Jeśli użycie kodu szesnastkowego nie jest w ogóle możliwe, czy mogę użyć kodu Unicode zamiast kodu szesnastkowego dla zestawu znaków („अ-व”)?

Używam Ubuntu 10.04


1
Co masz na myśli mówiąc „nie działa”? Również -vodwraca dopasowanie, z tekstu pytania wydaje się, że nie jest to, czego chcesz.
Christian.K,

@ Christian.K Przepraszam za opóźnienie ... Zredagowałem pytanie, proszę spojrzeć.

Nadal czekam na odpowiednią odpowiedź. :(
Dhrubo Bhattacharjee

Odpowiedzi:


21

Spójrz na to pytanie .

Tekst jest zwykle kodowany w UTF-8; więc musisz użyć wartości szesnastkowych bajtów używanych w kodowaniu utf-8.

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

i

grep '[अ-व]'

są równoważne i wykonują dopasowanie oparte na ustawieniach regionalnych (tzn. dopasowanie jest zależne od reguł sortowania skryptu devanagari (to znaczy, że dopasowanie to NIE jest „dowolny znak między \ u0905 a \ 0935”, ale „wszystko sortuje między devanagari A i devanagari VA ”; mogą występować różnice.

Z drugiej strony masz to (uwaga -P):

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

spowoduje to dopasowanie binarne z tymi wartościami bajtów .


2
Proszę wyjaśnić prefiks "["$'i sufiks"]"
Jonathan Komar

6

Jeśli ucieczka powłoki jest wystarczająca, możesz użyć następującej $'\xHH'składni:

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

Czy to wystarczy dla twojego przypadku użycia?


echo 'अ-व' | hddaje mie0 a4 85 - e0 a4 b5
enzotib

Rzeczywiście PO dało wartości UNICODE, nie szesnastkowym zrzuca w UTF-8: - / Ponieważ grepnie jest związane z żadnym lib, chyba że nie jest możliwe, aby konwersja zakres przeprowadzić grep: - /
Stephane GIMENEZ

1
Btw zshjest w stanie interpretować "\u0900"i "\u097F", ale zachowanie będzie zależeć od ciągłości zakodowanego UTF-8 (prawdopodobnie tak jest).
Stéphane Gimenez

Bez grep -v "<[" $ '\ x09 \ x00' "-" $ '\ x09 \ x7F' "] * \ s" daje następujące wyjście <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> .... Nie należy się tego spodziewać. :(, Czy mogę użyć Unicode zamiast kodu szesnastkowego lub zestawu znaków ('अ-व')?
Dhrubo Bhattacharjee

6

Zapisana wartość „szesnastkowa” 0x0900jest dokładnie wartością punktu kodowego UNICODE, również w systemie szesnastkowym.

kod szesnastkowy 0900 (zamiast अ)

Wierzę, że to, co chcesz powiedzieć, jest to kod szesnastkowy punkt UNICODE: U0905.

Znak U-0900 nie jest jeden użyłeś: .
Ten znak to U0905 , część tej strony Unicode lub wymieniony na tej stronie .

W bash(instalowany domyślnie w Ubuntu) lub bezpośrednio z programem w: /usr/bin/printf(ale nie z shprintf) znak Unicode można utworzyć za pomocą:

$ printf '\u0905'

$ /usr/bin/printf '\u0905'

Jednak ten znak, który pochodzi z numeru punktu kodowego, może być reprezentowany przez kilka strumieni bajtów, w zależności od używanej strony kodowej.
Powinno być oczywiste, że \U0905jest 0x09 0x05w UTF-16 (UCS-2 itp.)
I 0x00 0x00 0x09 0x05w UTF-32.
To może nie być oczywiste, ale w utf-8 jest reprezentowane przez 0xe0 0xa4 0x85:

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

Jeśli ustawienia regionalne konsoli są podobne en_US.UTF-8.

Mówię o powłoce, ponieważ jest to ta, która przekształca ciąg znaków w to, co otrzymuje aplikacja. To:

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

sprawia, że ​​grep „widzi” potrzebną postać.
Aby zrozumieć powyższą linię, możesz użyć echa:

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

Następnie możemy zbudować zakres postaci, zgodnie z twoją prośbą:

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

To odpowiada na twoje pytanie:

Jak mogę użyć kodu szesnastkowego zamiast अ i व?


Jest to zdecydowanie najlepsza odpowiedź --- wyraźnie dotyczy problemu reprezentacji punktów unicode w powłoce i pokazuje, jak poruszać się między nimi w kodzie szesnastkowym.
Stefan

2

chcieliśmy przekonwertować otwartą podwójną wycenę i zamknij podwójną wycenę na zwykłe podwójne cytaty („). Także pojedynczą wycenę non-ascii na zwykłą pojedynczą wycenę (').

aby zobaczyć je w pliku (powłoka bash Ubuntu):

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

przetłumacz je:

$ /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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.