web-dev-qa-db-ja.com

`grep`で16進コードを使用して文字を指定する方法

次のコマンドを使用して、16進コード0900(अの代わりに)から097F(वの代わりに)の文字セット範囲をgrepしています。 अとवの代わりに16進コードを使用するにはどうすればよいですか?

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

上記のコマンドでअとवの代わりに16進コードを使用したいだけです。

16進コードを使用することがまったく不可能である場合、文字セット( 'अ-व')に16進コードの代わりにユニコードを使用できますか?

Ubuntu 10.04を使用しています

29

grep:日本語の漢字を含むすべての行を検索 を見てください。

テキストは通常​​UTF-8でエンコードされます。そのため、UTF-8エンコーディングで使用されるバイトの16進値を使用する必要があります。

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

そして

grep '[अ-व]'

は同等であり、ロケールベースのマッチングを実行します(つまり、マッチングはデーバナーガリー文字のソート規則に依存します(つまり、マッチングはです)[〜#〜]ではありません[〜# 〜]「\ u0905と\ 0935の間の任意の文字」ではなく、「デーバナーガリAとデーバナーガリーVAの間で並べ替えるもの」;違いがある可能性があります。

$'...'は、bash、ksh、およびzshの「ANSI-Cエスケープ文字列」構文です。これは、文字を入力する簡単な方法です。\uXXXXおよび\UXXXXXXXXエスケープを使用して、bashおよびzshのコードポイントを直接要求することもできます。 。)

一方、あなたはこれを持っています(注-P):

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

これは、これらのbyte値と一致するbinaryを実行します。

23
Pablo Saratxaga

シェルのエスケープで十分な場合は、$'\xHH'このような構文:

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

あなたのユースケースにはそれで十分ですか?

7

「16進数」の値0x0900は、まさに16進数のUNICODEコードポイントの値です。

16進コード0900(अの代わり)

あなたの言うことは、16進数のUNICODEコードポイントU0905だと思います。

U-0900の文字は使用したものではありません:
その文字はU0905このUnicodeページ の一部、または このページ にリストされています。

bash(デフォルトではUbuntuにインストールされています)、または/usr/bin/printfsh printfではない)のプログラムで直接、Unicode文字を次のように生成できます。

$ printf '\u0905'
अ
$ /usr/bin/printf '\u0905'
अ

ただし、コードポイント番号に由来するその文字は、使用するコードページに応じて、いくつかのバイトストリームで表すことができます。
\U0905がUTF-16(UCS-2など)では0x09 0x05であることは明らかです。
および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

それはあなたの質問に答えます:

अとवの代わりに16進コードを使用するにはどうすればよいですか?

6
Isaac

非ASCIIの開始二重引用符と終了の二重引用符を通常の二重引用符( ")に変換する必要がありました。非ASCIIの単一引用符も通常の単一引用符( ')に変換しました。

ファイルでそれらを表示するには(ubuntu bash Shell):

$ 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
2
Gaius Gracchus