Wie spezifiziere ich Zeichen mit Hexadezimalcodes in `grep`?

27

Ich verwende den folgenden Befehl, um den Zeichensatzbereich für den Hexadezimalcode 0900 (anstelle von अ) bis 097F (anstelle von व) zu ermitteln. Wie kann ich hexadezimalen Code anstelle von अ und व verwenden?

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

Ich erhalte folgende Ausgabe:

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

Ich möchte nur hexadezimalen Code anstelle von अ und व im obigen Befehl verwenden.

Kann ich Unicode anstelle von Hexadezimalcode für den Zeichensatz ('अ-व') verwenden, wenn die Verwendung von Hexadezimalcode überhaupt nicht möglich ist?

Ich benutze Ubuntu 10.04

Dhrubo Bhattacharjee
quelle
1
Was meinst du mit "nicht arbeiten"? Auch -vinvertiert das Spiel, aus Ihrer Frage Text scheint es , dass ist nicht das, was Sie wollen.
Christian.K
@ Christian.K Entschuldigung für die Verspätung ... Ich habe die Frage bearbeitet, bitte schauen Sie.
Ich warte immer noch auf eine passende Antwort. :(
Dhrubo Bhattacharjee

Antworten:

21

Schau dir diese Frage an .

Text wird normalerweise in UTF-8 codiert. Sie müssen also die hexadezimalen Werte der in der utf-8-Codierung verwendeten Bytes verwenden.

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

und

grep '[अ-व]'

gleichwertig sind, und sie führen eine locale-based Matching (das heißt, Anpassung ist auf den Sortierregeln devanagari Skript abhängig (das heißt, ist der passende NICHT „jede char zwischen \ u0905 und \ 0935“ , sondern „etwas zwischen devanagari Sortier A und devanagari VA "; es kann Unterschiede geben.

Auf der anderen Seite haben Sie Folgendes (Anmerkung -P):

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

Dadurch wird ein binärer Abgleich mit diesen Bytewerten durchgeführt .

Pablo Saratxaga
quelle
2
Bitte erläutern Sie das Präfix "["$'und Suffix"]"
Jonathan Komar
6

Wenn Shell-Escaping ausreicht, können Sie die folgende $'\xHH'Syntax verwenden:

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

Ist das genug für Ihren Anwendungsfall?

Stéphane Gimenez
quelle
echo 'अ-व' | hdgibt mire0 a4 85 - e0 a4 b5
Enzotib
In der Tat hat das OP Unicode-Werte angegeben, keine hexadezimalen Dumps in UTF-8-Codierung: - / Da grepkeine Verknüpfung mit einer Bibliothek besteht, kann die Bereichskonvertierung vermutlich nicht von grep durchgeführt werden: - /
Stéphane Gimenez
1
Übrigens, es zshist in der Lage zu interpretieren "\u0900"und "\u097F", aber das Verhalten wird davon abhängen, dass der UTF-8-codierte Bereich kontinuierlich ist (wahrscheinlich ist es das).
Stéphane Gimenez
No grep -v "<[" $ '\ x09 \ x00' "-" $ '\ x09 \ x7F' "] * \ s" gibt die folgende Ausgabe aus: <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> .... Dies wird nicht erwartet. :(, Kann ich Unicode anstelle von Hexadezimalcode oder Zeichensatz ('अ-व') verwenden?
Dhrubo Bhattacharjee
6

Der "hexadezimale" Wert, den 0x0900Sie geschrieben haben, ist genau der Wert des UNICODE-Codepunkts, der ebenfalls hexadezimal ist.

Hexadezimalcode 0900 (anstelle von अ)

Ich glaube , dass Sie meinen , was zu sagen ist der hexadezimale Unicode - Codepunkt: U0905.

Das Zeichen an U-0900 ist nicht diejenige , die Sie verwendet: .
Dieses Zeichen ist U0905 , Teil dieser Unicode-Seite oder auf dieser Seite aufgeführt .

In bash(standardmäßig in Ubuntu installiert) oder direkt mit dem Programm unter: /usr/bin/printf(aber nicht mit shprintf) könnte ein Unicode-Zeichen erzeugt werden mit:

$ printf '\u0905'

$ /usr/bin/printf '\u0905'

Dieses Zeichen, das von einer Codepunktnummer stammt, kann jedoch in Abhängigkeit von der verwendeten Codepage durch mehrere Byteströme dargestellt werden.
Es sollte offensichtlich sein, dass \U0905es sich 0x09 0x05um UTF-16 (UCS-2 usw.)
und 0x00 0x00 0x09 0x05UTF-32 handelt.
Es mag nicht offensichtlich sein, aber in utf-8 wird es dargestellt durch 0xe0 0xa4 0x85:

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

Wenn das Gebietsschema Ihrer Konsole ähnlich ist en_US.UTF-8.

Und ich spreche von der Shell, weil sie einen String in das verwandelt, was die Anwendung empfängt. Dies:

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

macht grep "sehen" den Charakter, den Sie brauchen.
Um die obige Zeile zu verstehen, können Sie echo verwenden:

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

Dann können wir einen Zeichenbereich erstellen, wie Sie es wünschen:

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

Das beantwortet Ihre Frage:

Wie kann ich hexadezimalen Code anstelle von अ und व verwenden?

Sorontar
quelle
Dies ist bei weitem die beste Antwort - es geht eindeutig um die Darstellung von Unicode-Punkten in der Shell und zeigt, wie man zwischen diesen Hex-Codes hin und her wechselt.
Stefano
2

wir wollten das offene doppelte Anführungszeichen ohne ASCII-Zeichen und das geschlossene doppelte Anführungszeichen in reguläre doppelte Anführungszeichen (") umwandeln. Auch das einfache Anführungszeichen ohne ASCII-Zeichen sollte in reguläre einfache Anführungszeichen (') umgewandelt werden.

um sie in der Datei zu sehen (Ubuntu Bash Shell):

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

übersetze sie:

$ /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
Gaius Gracchus
quelle