我有一种感觉,这strings
阻碍了我在这里的努力。不幸的是,我想要使用的二进制文件strings
每个文件都会产生多个匹配项,尽管 100% 的规则是其中一个文件恰好包含NUL
末尾带有一个字符的字符串。这就是我想要的字符串。我也在以这种方式工作以确保误报被消除从一开始就。
不幸的是,似乎strings
无法教导如何保留空字节,因此我可以grep
for some_expression\0
.
示例行:(简化)
$ find . -maxdepth 1 -type f -size +1M -print0 | xargs -0 strings -fwn 3 | grep -w 'XYZ'
如果strings
可以告诉保持角色\0
,它甚至会允许... | grep -w 'XYZ[^[:print:]]'
稍后出现类似管道末端的东西。但是,当然,grep
只要管道中的前面的命令已经完成,就无能为力消除了'\0'。
我什至想到了一种(相当丑陋的)方法来解决这个问题,即在tr
正在处理的整个文件中将每个“\0”字符转换为“\177”(十进制255)。但这可能会产生太多误报。
还有更好的解决方案吗?
补充说明:虽然这个问题只涵盖最常见的情况 ( NUL
),但最佳解决方案将定义为也适合轻松适应用于字符串终止的其他不可打印字符的解决方案。
答案1
做好grep
的工作strings
。如果您有 GNU grep,请传递-z
选项以使其读取空分隔记录而不是换行分隔记录。这也将在文件末尾匹配,但在实践中应该没问题。
find . -maxdepth 1 -type f -size +1M -print0 |
xargs -0 grep -Eoz '[[:print:]]{3,}$'
如果您没有 GNU 实用程序,请传递文件tr
以将空字节与换行符交换。当你这样做时,将tr
垃圾字符设置为不可打印的字符。
find . -type d -prune -o -type f -size +1024k -exec sh -c '
for x; do
<"$x" tr \\0\\n \\n\\0 | tr -dsC "[:print:]" \\n |
grep ...
done
' _ {} +