因此,在帮助某人调试某些代码时,我意识到他们的输出中有一些奇怪的字符,即 和 (十六进制的\ xc0和\ xd0)。
我想在大文本输出文件中找到这些字符。
我已设法使用sublime找到这些字符,方法是在\xc0
或\xd0
作为查询的查找中启用正则表达式选项。我还通过在bash中执行grep
设法grep $'\xc0' filename
。
现在困扰我的是,如果我对-P
使用grep
选项,它就会拒绝找到这些字符。
grep -P "\xc0" filename
不打印任何包含该字符的文件(上面的其他两种方法会成功找到它),这让我很烦恼我想知道为什么这不会工作
我已经阅读了其他一些帖子,其中提出了-P
选项以及"[\x80-\xff]"
,但由于某种原因我无法让它们工作:\
grep -P
很长一段时间以来一直是好朋友:(感谢任何帮助和提示!
我正在使用GNU grep。
修改
我实际上尝试了2个Linux发行版。
printf "\xc0"
在终端中打印出任何内容,但是将其打印到>
的文件中,然后以崇高的方式打开将显示该字符。
printf "\xc0" > foo
grep $'\xc0' foo > out1
grep -P '\xc0' foo > out2
grep -P '\x{c0}' foo > out3
out{1,2,3}
都是空的。
printf
打印一些东西 - 问号dark thingy printf "\xc0"
打印出 (实际上看起来像这样)
printf "\xc0" > foo
grep $'\xc0' foo > out1
grep -P '\xc0' foo > out2
grep -P '\x{c0}' foo > out3
只有out1
包含该字符。
答案 0 :(得分:0)
首先需要做的是在变量内部创建要搜索的确切字节。
像这样的东西:
a=$(echo -e '\xc0)
a=$'\xc0'
a=$(printf '\xc0')
a=$(echo -e '\300') # 300 is 0xC0 in octal
a=$'\300'
a=$(printf '\300')
a=$(echo "c0" | xxd -r -p)
我可以尝试提出其他一些方法,但我希望你明白这一点。
然后,您可以尝试使用grep:
搜索byte
echo $'Testing this: \xC0 byte' | grep "$a"
并且,如果您使用具有utf-8(最常见)的语言环境将失败。 如果您更改为ISO-8859-1区域设置,则可以使用:
LC_ALL=en_US.iso88591 echo $'Testing this: \xC0 byte' |
LC_ALL=en_US.iso88591 grep -P "$a"
或者,如果您不介意启动新的bash实例:
$ bash
$ export LC_ALL=en_US.iso88591
$ echo $'Testing this: \xC0 byte' | grep -P "$a"
通过执行exit
返回旧的bash环境
这可能有效或无效,具体取决于您的系统。
让我们探索另一面:角色。
你应该理解一个非常重要的转折点 字节不是字符。好吧,有时,纯粹的运气,它是。
但是除了128个ASCII字符,其中一个字节是一个字符(不是UTF-16或UTF-32。让我们也忘记EBCDIC),所有1,114,112(17×65,536)UNICODE代码点都有多个字节 1 。
在这种情况下,您应该要求UNICODE代码点为十六进制0xC0
在现代狂欢中,像这样:
$ printf '\U00C0`
À
哪个是this character: LATIN CAPITAL LETTER A WITH GRAVE
如果语言环境是ISO-8859-1(至少是ISO-8859-15),则将编码为一个字节;如果语言环境为utf-8,则将编码为两个字节。
$ a=$(printf '\UC0')
$ printf 'Testing \U00C0 character' | grep -P "$a"
Testing À character
如果更改LC_ALL变量,它也会起作用。好吧,我的意思是grep将检测到该字符,但由于更改的语言环境,打印的行可能无法正确呈现该字符。
如果文件具有此字符且文件的编码正确。 Grep将使用变量中字符的值。