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
文本通常以 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)
这将与这些字节值进行二进制匹配。
如果 shell 转义就足够了,您可以使用如下$'\xHH'语法:
grep -v "<["$'\x09\x00'"-"$'\x09\x7F'"]*\s"
Run Code Online (Sandbox Code Playgroud)
这对您的用例来说足够了吗?
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)
但是,来自代码点编号的字符可以由几个字节流表示,具体取决于使用的代码页。
很明显,这\U0905是0x09 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)
那回答你的问题:
我如何使用十六进制代码代替 ? 和 ??