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
- 您搜索的十六进制字节从不包含换行符(
)[1]0xa
- 如果它们包含NUL(
),则必须通过文件(0x
)而不是通过直接参数提供-f
搜索字符串grep
- 如果它们包含NUL(
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
然后减少到:
该命令几乎适用于BSDgrep
,但报告的字节偏移量始终是匹配模式的行的开始。换句话说:只有在文件中匹配之前没有换行符时,字节偏移量才会正确。
此外,BSD
grep
不支持将NUL(0x0
)字节指定为搜索字符串的一部分,即使通过带有-f
的文件提供也不支持
- 请注意,基于使用
的find
,它与-exec+
一样,一次将命令行中适合的文件名传递给xargs
grep
- 通过让
直接搜索字节序列,不需要grep
:xxd
- 序列被指定为,这意味着转义序列由shell扩展为文本,从而使Grep能够以文本形式搜索结果字符串(通过
),这会更快。-F
链接文章来自
手册,但它们也适用于bash
(和zsh
)。ksh
- GNU Grep的另一种选择是将
(支持PRCEs,Perl兼容的正则表达式)与非预扩展的转义序列一起使用,但这会更慢:-P
Grep-PHoab'\x{0e}\x{8b}\x{02}'
- GNU Grep的另一种选择是将
确保LC_ALL=C
将每个字节视为自己的字符,而不应用任何编码规则grep
将搜索字符串视为文本(而不是正则表达式)-F
将相关的输入文件名前置到每个输出行;请注意,当给定多个filename参数时,Grep会隐式执行此操作-H
只报告匹配的字符串(字节序列),而不是整行(行的概念在二进制文件中没有任何意义)[2]-o
将二进制文件视为文本文件(如果没有这一点,Grep将只打印文本-a
,用于具有匹配项的二进制输入文件)二进制文件匹配项
报告匹配的字节偏移量-b
- 序列被指定为,这意味着转义序列由shell扩展为文本,从而使Grep能够以文本形式搜索结果字符串(通过
-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上运行此程序。这会是一个问题吗?不幸的是,可能是的。然而,也许安装GNUgrep
是您的一个选择。看一下我的答案,让我们继续讨论。在安装GNUgrep
之后,我仍然有一些问题:一个简单的方法可以工作,但是我无法让您的命令通过简单的搜索00
返回任何内容。我愿意接受任何解决方案