【问题标题】:Issues matching zero-byte using grep使用 grep 匹配零字节的问题
【发布时间】:2021-04-07 12:52:44
【问题描述】:

我正在尝试在文件中查找 7zip 版本 3 文件头。根据documentation,它们应该是这样的:

00: 6 bytes: 37 7A BC AF 27 1C        - Signature 
06: 2 bytes: 00 04                    - Format version

所以我构建了这个应该匹配它们的 grep 命令:

grep --only-matching --byte-offset --binary --text $'7z\xBC\xAF\x27\x1C\x00\x03'

但它也匹配以0000结尾的字符串:

% xxd -p -r <<< "aaaa 377a bcaf 271c 0000 bbbb 00 377a bcaf 271c 0003" | grep --only-matching --byte-offset --binary --text $'7z\xBC\xAF\x27\x1C\x00\x03'
2:7z'
13:7z'

我期望的输出只是13:7z'

【问题讨论】:

  • \x00 不能将零字节作为参数的一部分传递
  • 您能详细说明一下吗?是因为它被shell解释了吗?用grep匹配零字节是不可能的吗?你是说根本没有解决办法?
  • Could you elaborate? 是的。 Is it because it gets interpreted by the shell? 不,这是因为 C 语言是如何被发明的。现在我会说:因为“历史原因”。 Is it impossible to match zero-bytes with grep? 不,有可能。 Are you saying there is no solution at all?没有。
  • 这就是我所说的“由 shell 解释”的意思 $'string' 指示 shell 将转义序列转换为其文字表示,然后将它们传递给 grep,然后触发 strlen 的问题。不过谢谢。 ??????
  • 好吧,这真的是在那之前,因为 shell 调用 execveexecve 需要零终止的字符串。所以实际上是在grep 被执行之前。但是使用“strlen”很容易解释。

标签: shell grep gnu-coreutils


【解决方案1】:

不可能将零字节作为参数的一部分传递。因为字符串在C 中以零字节结尾,所以grep 在运行strlen(argv[...]) 时不会“看到”零字节之后的任何内容。

如果正则表达式中没有换行符,您可以使用--file=

xxd -p -r <<< "aaaa 377a bcaf 271c 0000 bbbb 00 377a bcaf 271c 0003" |
LC_ALL=C grep --only-matching --byte-offset --binary --text -f <(
    echo -n 7z;
    echo BCAF271C0003 | xxd -r -p
)

https://www.gnu.org/software/grep/manual/grep.html#Matching-Non_002dASCII

或者使用 PERL 正则表达式

xxd -p -r <<< "aaaa 377a bcaf 271c 0000 bbbb 00 377a bcaf 271c 0003" | 
LC_ALL=C grep --only-matching --byte-offset --binary --text -P '7z\xBC\xAF\x27\x1C\x00\x03'

在处理二进制文件时,请记住使用区域设置 LC_ALL=C 禁用 UTF-8 序列处理。

注意:&lt;&lt;&lt;""$'string' 在任何 shell 中都不可用 - 它们在 bash 中可用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-03
    • 2011-10-02
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2014-10-20
    • 1970-01-01
    • 2013-10-08
    相关资源
    最近更新 更多