计算二进制数据的出现次数

9 人关注

我需要计算二进制文件中十六进制字符串 0xFF 0x84 0x03 0x07 的出现次数,不需要太多麻烦......有没有一种快速的方法可以从linux命令行中搜索到这些数据,或者我应该写专门的代码来做这件事?

linux
binary
grep
Ferenc Deak
Ferenc Deak
发布于 2013-03-11
5 个回答
mwfearnley
mwfearnley
发布于 2013-08-15
已采纳
0 人赞同

Patterns without linebreaks

如果你的 grep 的版本使用 -P 参数,那么你可以使用 grep -a -P ,在二进制文件中搜索一个任意的二进制字符串(没有换行符)。 这与你想要的很接近。

grep -a -c -P '\xFF\x84\x03\x07' myfile.bin
  • -a确保二进制文件不会被跳过

  • -c outputs the count

  • -P指定你的模式是一个Perl兼容的正则表达式(PCRE),它允许字符串包含上述\xNN格式的十六进制字符。

    不幸的是,grep -c只会计算图案出现的 "行数",而不是实际出现的次数。

    为了得到grep的确切出现次数,似乎你需要做的是。

    grep -a -o -P '\xFF\x84\x03\x07' myfile.bin | wc -l
    

    替换代码11】将每个匹配项分离到自己的行中,wc -l对行进行计数。

    Patterns containing linebreaks

    如果你确实需要搜索换行符,我能想到的一个变通方法是使用tr将该字符换成另一个不在你搜索范围内的字符。

    # set up test file (0a is newline)
    xxd -r <<< '0:08 09 0a 0b 0c 0a 0b 0c' > test.bin
    # grep for '\xa\xb\xc' doesn't work
    grep -a -o -P '\xa\xb\xc' test.bin | wc -l
    # swap newline with oct 42 and grep for that
    tr '\n\042' '\042\n' < test.bin | grep -a -o -P '\042\xb\xc' | wc -l
    

    (请注意,042八进制是双引号"中的符号。ASCII.)

    另一种方法,如果你的字符串不包含Nulls(0x0),可以使用-z标志,并在传递给wc之前,将Nulls换成连字符。

    grep -a -o -P -z '\xa\xb\xc' test.bin | tr '\0\n' '\n\0' | wc -l
    

    (Note that -z and -P may be实验性互相结合。 但对于简单的表达式和没有Nulls的表达式,我想它是没问题的)。

  • 我注意到,这对我来说并不奏效,但我想明白了......根据我的地区设置,它将输入视为UTF-8,而没有找到我的模式,这在UTF-8中是一个无效的字符。 将 LANG LC_ALL 设置为 C 就可以了,也就是说,这样做。【替换代码3
    hiteshradia
    hiteshradia
    发布于 2013-08-15
    0 人赞同

    use hexdump like

    hexdump -v -e '"0x" 1/1 "%02X" " "' <filename> | grep -oh "0xFF 0x84 0x03 0x07" |wc -w

    替换代码1】将输出指定格式的二进制文件,如0xNN。

    替换代码2】将找到所有的字符串的出现,而不考虑在一行中重复出现的相同字符串。

    替换代码3】会给你最后的计数。

    Kent
    Kent
    发布于 2013-08-15
    0 人赞同

    did you try grep -a ?

    来自grep手册页。

    -a, --text
                  Process a binary file as if it were text; this is equivalent to the --binary-files=text option.
        
    Chris Seymour
    Chris Seymour
    发布于 2013-08-15
    0 人赞同
    $ hexdump a.out | grep -Ec 'ff ?84 ?03 ?07'
        
    我的 hexdump (默认情况下)包裹了这些行,在每一行前加了一个偏移量,并交换了字节对的endian。 这种格式使得grep要抓住所有的情况是一个真正的挑战,同时还要避免偏移量带来的假阳性。
    entheh
    entheh
    发布于 2013-08-15
    0 人赞同

    这并没有完全回答你的问题,但确实解决了搜索字符串为ASCII但文件为二进制时的问题。