Bash 如何从Linux命令行检查二进制文件是否包含在另一个二进制文件中?
基本上我想要一个“以二进制字符串为模式的多行grep” 例如:Bash 如何从Linux命令行检查二进制文件是否包含在另一个二进制文件中?,bash,grep,posix,gnu-coreutils,Bash,Grep,Posix,Gnu Coreutils,基本上我想要一个“以二进制字符串为模式的多行grep” 例如: printf '\x00\x01\n\x02\x03' > big.bin printf '\x01\n\x02' > small.bin printf '\x00\n\x02' > small2.bin 那么,以下内容应适用: small.bin包含在big.bin small2.bin不包含在big.bin 我不想将文件转换为ASCII十六进制表示形式,如图所示xxd,例如at:,因为这感觉很浪费 理想情
printf '\x00\x01\n\x02\x03' > big.bin
printf '\x01\n\x02' > small.bin
printf '\x00\n\x02' > small2.bin
那么,以下内容应适用:
包含在small.bin
big.bin
不包含在small2.bin
big.bin
xxd
,例如at:,因为这感觉很浪费
理想情况下,该工具应该处理不适合内存的大型文件
请注意,以下尝试无效
grep-f
匹配不应该匹配的位置,因为它必须拆分换行符:
grep -F -f small.bin big.bin
# Correct: Binary file big.bin matches
grep -F -f small2.bin big.bin
# Wrong: Binary file big.bin matches
在$(cat)
中的Shell替换失败,因为它是失败的,所以字符串在第一次0
时被截断
grep -F "$(cat small.bin)" big.bin
# Correct: Binary file big.bin matches
grep -F "$(cat small2.bin)" big.bin
# Wrong: Binary file big.bin matches
有人问了一个C问题:但是是否可以使用任何广泛可用的CLI(希望是POSIX或GNU coreutils)工具
值得注意的是,实现一个非朴素的算法,例如,并不完全是微不足道的
我可以按如下方式编写一个工作的Python one liner,但它不适用于不适合内存的文件:
grepbin() ( python -c 'import sys;sys.exit(not open(sys.argv[1]).read() in open(sys.argv[2]).read())' "$1" "$2" )
grepbin small.bin big.bin && echo 1
grepbin small2.bin big.bin && echo 2
我还可以在GitHub上找到以下两个工具:
- 在C语言中,可使用(惊人:-)安装:
- 带锈,可与以下部件一起安装:
cargo install bgrep
bgrep $(xxd -p small.bin | tr -d '\n') big.bin
因为用xxd
转换小文件并不重要,但这不是很好
无论如何,如果我要实现该特性,我很可能会将其应用到上面的Rust库中
bgrep还提到:
在Ubuntu 20.10上测试
如何从Linux命令行检查二进制文件是否包含在另一个二进制文件中
POSIX可移植的方法是使用od
转换为十六进制,然后使用grep
检查子字符串,以及中间的一些sed
脚本
通常的正常便携方式是使用xxd
而不是od
:
xxd -p small.bin | tr -d '[ \n]' > small.bin2
xxd -p big.bin | tr -d '[ \n]' > big.bin2
grep -F -f small.bin2 big.bin2
使用busybox
在alpine
上的docker
中进行了良好测试
但是:
我不想将文件转换为ASCII十六进制表示形式,如图所示
那么您就不能在shell中使用二进制文件了。选择另一种语言。Shell是专门为解析好看的人类可读字符串而创建的—对于其他任何东西,它都是非常令人不愉快的,对于零字节的文件xxd
是您键入的第一件事
我可以编写一个工作的Python一行程序,如下所示
awk
也是POSIX,在任何地方都可以使用-我相信在awk
方面更熟练的人可能会来编写python脚本的1:1,但是:
但它不适用于不适合内存的文件:
grepbin() ( python -c 'import sys;sys.exit(not open(sys.argv[1]).read() in open(sys.argv[2]).read())' "$1" "$2" )
grepbin small.bin big.bin && echo 1
grepbin small2.bin big.bin && echo 2
所以,写一个不同的算法,它不会这样做
总的来说,当给出不使用xxd
(或od
)将零字节二进制文件转换为十六进制表示的约束时:
是否可以使用任何广泛可用的CLI(希望是POSIX或GNU coreutils)工具
不,写你自己的程序。您也可以用perl
编写,它有时在没有python
的机器上可用
如何从Linux命令行检查二进制文件是否包含在另一个二进制文件中
POSIX可移植的方法是使用od
转换为十六进制,然后使用grep
检查子字符串,以及中间的一些sed
脚本
通常的正常便携方式是使用xxd
而不是od
:
xxd -p small.bin | tr -d '[ \n]' > small.bin2
xxd -p big.bin | tr -d '[ \n]' > big.bin2
grep -F -f small.bin2 big.bin2
使用busybox
在alpine
上的docker
中进行了良好测试
但是:
我不想将文件转换为ASCII十六进制表示形式,如图所示
那么您就不能在shell中使用二进制文件了。选择另一种语言。Shell是专门为解析好看的人类可读字符串而创建的—对于其他任何东西,它都是非常令人不愉快的,对于零字节的文件xxd
是您键入的第一件事
我可以编写一个工作的Python一行程序,如下所示
awk
也是POSIX,在任何地方都可以使用-我相信在awk
方面更熟练的人可能会来编写python脚本的1:1,但是:
但它不适用于不适合内存的文件:
grepbin() ( python -c 'import sys;sys.exit(not open(sys.argv[1]).read() in open(sys.argv[2]).read())' "$1" "$2" )
grepbin small.bin big.bin && echo 1
grepbin small2.bin big.bin && echo 2
所以,写一个不同的算法,它不会这样做
总的来说,当给出不使用xxd
(或od
)将零字节二进制文件转换为十六进制表示的约束时:
是否可以使用任何广泛可用的CLI(希望是POSIX或GNU coreutils)工具
不,写你自己的程序。您也可以在
perl
中编写它,它有时在没有python
rep-f匹配的机器上可用,因为它必须拆分换行符:
,并且还解析regex<代码>grep“$(cat small.bin)”不仅在零字节时失败grep
需要一个正则表达式。请注意,您的是否可以使用任何广泛可用的CLI
进入“寻找工具推荐”栏。@KamilCuk true,为非正则表达式添加了-F
。如果它关闭,我会在其他地方发布,通常的过程。“$(带空的cat文件)”
会设置自己失败,因为NUL不能存储在C字符串中,bash中的所有字符串都是NUL分隔的C字符串。就这一点而言,如果grep
使用能够包含NUL文本的字符串,我会非常惊讶——不,惊讶——这将是构建一个版本的更合理的开始