如何使用十六进制表示

时间:2016-11-25 19:19:38

标签: regex linux bash grep

因此,在帮助某人调试某些代码时,我意识到他们的输出中有一些奇怪的字符,即 和 (十六进制的\ 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发行版。

  • 在Ubuntu 14.04上使用bash:我的终端似乎不喜欢这个角色:\

printf "\xc0"在终端中打印出任何内容,但是将其打印到>的文件中,然后以崇高的方式打开将显示该字符。

printf "\xc0" > foo
grep $'\xc0' foo > out1
grep -P '\xc0' foo > out2
grep -P '\x{c0}' foo > out3

out{1,2,3}都是空的。

  • 在CentOS 7.2上使用bash:printf打印一些东西 - 问号dark thingy

printf "\xc0"打印出 (实际上看起来像这样)

printf "\xc0" > foo
grep $'\xc0' foo > out1
grep -P '\xc0' foo > out2
grep -P '\x{c0}' foo > out3

只有out1包含该字符。

1 个答案:

答案 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将使用变量中字符的值。