ascii字符串与二进制文件的"grep"偏移量

mgi*_*son 27 linux binary bash grep ascii

我正在生成二进制数据文件,这些文件只是连接在一起的一系列记录.每条记录包含一个(二进制)标题,后跟二进制数据.在二进制头内是一个长度为80个字符的ascii字符串.在某个地方,我编写文件的过程有点搞砸了,我试图通过检查每条记录的实际长度来调试这个问题.

似乎非常相关,但我不理解perl,所以我无法在那里得到公认的答案.bgrep我编译的其他答案指向,但它希望我提供一个十六进制字符串,我宁愿只有一个工具,我可以给它ascii字符串,它会在二进制数据中找到它,打印字符串和找到它的字节偏移量.

换句话说,我正在寻找一些像这样的工具:

tool foobar filename
Run Code Online (Sandbox Code Playgroud)

要么

tool foobar < filename
Run Code Online (Sandbox Code Playgroud)

它的输出是这样的:

foobar:10
foobar:410
foobar:810
foobar:1210
...
Run Code Online (Sandbox Code Playgroud)

例如匹配的字符串和匹配开始的文件中的字节偏移量.在这个示例中,我可以推断每条记录的长度为400字节.

其他限制:

  • 通过正则表达式搜索的能力很酷,但我不需要它来解决这个问题
  • 我的二进制文件很大(3.5Gb),所以我想尽可能避免将整个文件读入内存.

Har*_*non 32

grep --byte-offset --only-matching --text foobar filename
Run Code Online (Sandbox Code Playgroud)

--byte-offset选项打印每个匹配行的偏移量.

--only-matching选项使其为每个匹配实例而不是每个匹配行打印偏移量.

--text选项使grep将二进制文件视为文本文件.

您可以将其缩短为:

grep -oba foobar filename
Run Code Online (Sandbox Code Playgroud)

它适用于GNU版本grep,默认情况下附带linux.它不适用于BSD grep(默认情况下附带Mac).

  • 尝试添加 `-a` 选项以将二进制文件视为文本 (3认同)
  • 如果您在 grep 前面加上`LC_CTYPE=C`,它*可以*在 OS X grep 中工作;然而,最近(也许不是最近)的 OS X 有 grep 2.5.1,它有一个错误,它总是输出 0 作为字节偏移量。 (2认同)
  • 如果您只需要查找已知字符串,我建议使用 `grep -F`,因为它的开销要少得多。 (2认同)

Tho*_*hor 27

你可以使用strings这个:

strings -a -t x filename | grep foobar
Run Code Online (Sandbox Code Playgroud)

用GNU binutils测试.

例如,/bin/ls确实--help发生的地方:

strings -a -t x /bin/ls | grep -- --help
Run Code Online (Sandbox Code Playgroud)

输出:

14938 Try `%s --help' for more information.
162f0       --help     display this help and exit
Run Code Online (Sandbox Code Playgroud)

  • 我最终使用`strings -a -td filename | grep foobar`用十进制而不是十六进制写输出.否则,很好的答案似乎适用于不同风格的`grep`. (5认同)
  • `grep -oba` (参见 Hari Menon 的答案)要快得多,但使用 `strings` 允许您进行部分匹配。哪个答案更好取决于您的用例! (2认同)