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

Dhr*_*jee 36 shell grep character-encoding unicode

我正在使用以下命令将十六进制代码 0900(而不是?)的字符集范围 grep 到 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
Run Code Online (Sandbox Code Playgroud)

我得到以下输出:

    <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> 
    ...
Run Code Online (Sandbox Code Playgroud)

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

如果根本不可能使用十六进制代码,我可以使用 unicode 代替十六进制代码作为字符集 ('?-?') 吗?

我正在使用 Ubuntu 10.04

Pab*_*aga 26

查看grep:查找所有包含日语 kanjis 的行

文本通常以 UTF-8 编码;所以你必须使用 UTF-8 编码中使用的字节的十六进制值。

grep "["$'\xe0\xa4\x85'"-"$'\xe0\xa4\xb5'"]"
Run Code Online (Sandbox Code Playgroud)

grep '[?-?]'
Run Code Online (Sandbox Code Playgroud)

是等价的,并且它们执行基于语言环境的匹配(即,匹配取决于梵文脚本的排序规则(即匹配不是“\u0905 和 \0935 之间的任何字符”,而是“天城文之间的任何排序) A 和梵文 VA”;可能存在差异。

$'...'是 bash、ksh 和 zsh 的“ANSI-C 转义字符串”语法。这只是一种更简单的输入字符的方法。您也可以使用\uXXXX\UXXXXXXXX转义直接在 bash 和 zsh 中询问代码点。)

另一方面,你有这个(注意 -P):

grep -P "\xe0\xa4[\x85-\xb5]"
Run Code Online (Sandbox Code Playgroud)

这将与这些字节值进行二进制匹配。

  • 请解释前缀`"["$'`和后缀`"]"` (2认同)

Sté*_*nez 7

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

grep -v "<["$'\x09\x00'"-"$'\x09\x7F'"]*\s"
Run Code Online (Sandbox Code Playgroud)

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


ImH*_*ere 7

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

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

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

U-0900 中的字符不是您使用的字符:?
该字符是 U0905此 Unicode 页面的一部分,或在此页面上列出。

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

$ printf '\u0905'
?
$ /usr/bin/printf '\u0905'
?
Run Code Online (Sandbox Code Playgroud)

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

$ /usr/bin/printf '\u0905' | od -vAn -tx1
e0 a4 85
Run Code Online (Sandbox Code Playgroud)

如果您的控制台的语言环境类似于en_US.UTF-8.

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

grep "$(printf '\u0905')" file
Run Code Online (Sandbox Code Playgroud)

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

$ echo grep "$(printf '\u0905')" file
grep ? file
Run Code Online (Sandbox Code Playgroud)

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

$ echo grep "$(printf '[\u0905-\u097f]')" file
grep [?-?] file
Run Code Online (Sandbox Code Playgroud)

那回答你的问题:

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