如何在`grep`中使用十六进制代码指定字符?

如何在`grep`中使用十六进制代码指定字符?

我正在使用以下命令来 grep 十六进制代码 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> 
    ...

我只想在上面的命令中使用十六进制代码而不是 अ 和 व。

如果根本不可能使用十六进制代码,我可以使用 unicode 而不是字符集('अ-व')的十六进制代码吗?

我使用的是Ubuntu 10.04

答案1

看着grep:查找包含日语汉字的所有行

文本通常采用 UTF-8 编码;因此您必须使用 UTF-8 编码中使用的字节的十六进制值。

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]"

这将做一个二进制与那些相匹配字节值。

答案2

如果 shell 转义就足够了,您可以使用$'\xHH'如下语法:

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

这对于您的用例来说足够了吗?

答案3

您写入的“十六进制”值0x0900正是 UNICODE 代码点的值,也是十六进制的。

十六进制代码 0900(而不是 अ)

我相信你的意思是说十六进制UNICODE代码点:U0905

U-0900 处的字符不是您使用的字符:
该角色是U0905, 部分这个统一码页面,或列于这一页

bash(Ubuntu 中默认安装)中,或直接使用以下程序:(/usr/bin/printf但不能使用shprintf),可以使用以下命令生成 Unicode 字符:

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

但是,来自代码点编号的该字符可以由多个字节流表示,具体取决于使用的代码页。
很明显,它\U09050x09 0x05UTF-16(UCS-2 等)
0x00 0x00 0x09 0x05UTF-32 格式的。
它可能不明显,但在 utf-8 中它表示为0xe0 0xa4 0x85

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

如果您的控制台的区域设置类似于en_US.UTF-8.

我谈论的是 shell,因为它是将字符串转换为应用程序接收到的内容。这:

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

使 grep “看到”您需要的字符。
要理解上面的行,您可以使用 echo:

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

然后,我们可以根据您的要求构建字符范围:

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

这回答了你的问题:

如何使用十六进制代码代替 अ 和 व?

答案4

我们想要将非 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

相关内容