Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell 递归搜索二进制文件目录中的十六进制序列?_Shell_Zsh_Binaryfiles_Hexdump_Find Util - Fatal编程技术网

Shell 递归搜索二进制文件目录中的十六进制序列?

Shell 递归搜索二进制文件目录中的十六进制序列?,shell,zsh,binaryfiles,hexdump,find-util,Shell,Zsh,Binaryfiles,Hexdump,Find Util,当前我用于搜索某些十六进制值(例如0A 8b 02)的命令包括: find-类型f-非-name“*.png”-exec xxd-p{}\|grep“0a8b02”| | xargs-0-p4 鉴于以下目标,是否有可能改善这一点: 递归搜索文件 显示偏移量和文件名 排除具有特定扩展名的特定文件(上面的示例不会搜索.png文件) 速度:搜索需要直接处理200000个文件(大约50KB到1MB),总计约2GB 如果xargs能在4个处理器上正常工作,我不太有信心。另外,当grep找到匹配项时,我

当前我用于搜索某些十六进制值(例如
0A 8b 02
)的命令包括:

find-类型f-非-name“*.png”-exec xxd-p{}\|grep“0a8b02”| | xargs-0-p4

鉴于以下目标,是否有可能改善这一点:

  • 递归搜索文件
  • 显示偏移量和文件名
  • 排除具有特定扩展名的特定文件(上面的示例不会搜索
    .png
    文件)
  • 速度:搜索需要直接处理200000个文件(大约50KB到1MB),总计约2GB
如果
xargs
能在4个处理器上正常工作,我不太有信心。另外,当
grep
找到匹配项时,我打印文件名时遇到困难,因为它是从
xxd
管道传输的。有什么建议吗?

如果:

  • 你有GNU
    grep
  • 您搜索的十六进制字节从不包含换行符(
    0xa
    )[1]
    • 如果它们包含NUL(
      0x
      ),则必须通过文件(
      -f
      )而不是通过直接参数提供
      grep
      搜索字符串
使用搜索
0e 8b 02
的示例,以下命令将使您到达该位置:

LC_ALL=C find . -type f -not -name "*.png" -exec grep -FHoab $'\x{0e}\x{8b}\x{02}' {} + |
  LC_ALL=C cut -d: -f1-2
grep
命令生成如下输出行:

<filename>:<byte-offset>:<matched-bytes>
::
哪个
LC_ALL=C切-d:-f1-2
然后减少到

该命令几乎适用于BSD
grep
,但报告的字节偏移量始终是匹配模式的行的开始。
换句话说:只有在文件中匹配之前没有换行符时,字节偏移量才会正确。
此外,BSD
grep
不支持将NUL(
0x0
)字节指定为搜索字符串的一部分,即使通过带有
-f
的文件提供也不支持

  • 请注意,基于使用
    find
    -exec+
    ,它与
    xargs
    一样,一次将命令行中适合的文件名传递给
    grep
  • 通过让
    grep
    直接搜索字节序列,不需要
    xxd
    • 序列被指定为,这意味着转义序列由shell扩展为文本,从而使Grep能够以文本形式搜索结果字符串(通过
      -F
      ),这会更快。
      链接文章来自
      bash
      手册,但它们也适用于
      zsh
      (和
      ksh
      )。
      • GNU Grep的另一种选择是将
        -P
        (支持PRCEs,Perl兼容的正则表达式)与非预扩展的转义序列一起使用,但这会更慢:
        Grep-PHoab'\x{0e}\x{8b}\x{02}'
    • LC_ALL=C
      确保
      grep
      将每个字节视为自己的字符,而不应用任何编码规则
    • -F
      将搜索字符串视为文本(而不是正则表达式)
    • -H
      将相关的输入文件名前置到每个输出行;请注意,当给定多个filename参数时,Grep会隐式执行此操作
    • -o
      只报告匹配的字符串(字节序列),而不是整行(行的概念在二进制文件中没有任何意义)[2]
    • -a
      将二进制文件视为文本文件(如果没有这一点,Grep将只打印文本
      二进制文件匹配项
      ,用于具有匹配项的二进制输入文件)
    • -b
      报告匹配的字节偏移量
如果在给定的输入文件中最多可以找到1个匹配项,请添加
-m1


[1] 不能使用换行符,因为Grep总是将搜索模式字符串中的换行符视为分隔多个搜索模式。而且,Grep是基于行的,所以不能跨行匹配;GNU Grep的
-null data
选项按NUL字节分割输入可能会有所帮助,但前提是您的搜索字节序列不包含NUL字节;您还必须在与
-P
组合的正则表达式中将字节值表示为转义序列,因为您需要使用转义序列
\n
来代替实际的换行符


[2]
-o
需要使
-b
报告匹配的字节偏移量,而不是行开头的字节偏移量(如前所述,不幸的是,BSD Grep总是报告后者);此外,在这里只报告匹配本身是有益的,因为如果在二进制文件中没有行的概念,试图打印整行将导致不可预测的长输出行;但是,无论哪种方式,从二进制文件输出字节都可能会在终端中导致奇怪的渲染行为。

我会编写一个脚本,用于对单个二进制文件进行灰色化(成功时打印文件名),并在
find | xargs
中使用该脚本。您在zsh中,因此很难在子shell中定义函数。如果你决定把所有的东西都放在一个脚本中,你可以使用bash,它允许你导出一个函数。。。甚至不可能输出文件名?如果搜索字节序列从未包含
0xa
(即换行符),那么会有一个相当简单的解决方案-但听起来它们可以,对吗?另外,您是否正在使用GNU实用程序(Linux)?@mklement0不,序列永远不会包含
0xa
,不幸的是,我正在OSX上运行此程序。这会是一个问题吗?不幸的是,可能是的。然而,也许安装GNU
grep
是您的一个选择。看一下我的答案,让我们继续讨论。在安装GNU
grep
之后,我仍然有一些问题:一个简单的方法可以工作,但是我无法让您的命令通过简单的搜索
00
返回任何内容。我愿意接受任何解决方案