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


27

次のコマンドを使用して、16進コード0900(अの代わり)から097F(वの代わり)の文字セット範囲をgrepします。अとofの代わりに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> 
    ...

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

16進コードの使用がまったく不可能な場合、文字セット( 'hexadecimal-व')に16進コードの代わりにUnicodeを使用できますか?

Ubuntu 10.04を使用しています


1
「機能していない」とはどういう意味ですか?また-v、一致を逆にします。質問テキストから、あなたが望むものではないようです。
Christian.K

@ Christian.K遅れて申し訳ありません...私は質問を編集しました、見てください。

私はまだ適切な答えを待っています。:(
Dhrubo Bhattacharjee

回答:


21

この質問を見てください。

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

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

そして

grep '[अ-व]'

である(同等であり、それらは、ロケール・ベースのマッチングを行い、マッチングはマッチングがある、である(デーヴァナーガリースクリプトの仕分けルールに依存しないではなく、「デーヴァナーガリーの間でソート何でも「u0905と\ 0935 \の間に任意の文字」 Aとデバナガリ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

実際、OPはUTF-8エンコーディングの16進ダンプではなくユニコード値を提供しました:-/ greplibにリンクされていないため、grepで範囲変換を実行することはできないと思います:-/
StéphaneGimenez

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> ....これは予期されていません。:(、16進コードまたは文字セット( 'अ-व')の代わりにユニコードを使用できますか?
Dhrubo Bhattacharjee

6

0x0900記述した「16進数」の値は、UNICODEコードポイントの値であり、これも16進数です。

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

あなたが言っているのは、16進数のUNICODEコードポイントだと思いますU0905

U-0900の文字は、使用した文字ではありません:
その文字はU0905このUnicodeページの一部であるか、このページに記載されています)です。

bash(Ubuntuのデフォルトでインストールされた)、または直接プログラムで:/usr/bin/printf(ではないとshのprintf)、Unicode文字を用いて生成することができます:

$ printf '\u0905'

$ /usr/bin/printf '\u0905'

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

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

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


これは間違いなく最良の答えです。シェル内のユニコードポイントの表現の問題に明確に対処し、16進コード間を行き来する方法を示しています。
ステファノ

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.