如何计算文件中的字节数,将相同的字节分组?

如何计算文件中的字节数,将相同的字节分组?

示例:我有文件“mybinaryfile”,十六进制内容为:

A0 01 00 FF 77 01 77 01 A0

我需要知道这个文件中有多少个A0字节,有多少个01等等。结果可能是:

A0: 2
01: 3
00: 1
FF: 1
77: 2

有没有什么方法可以直接在 shell 中进行计数,或者我是否需要用任何语言编写一个程序来完成这个特定的任务?

答案1

这使用OD每行显示一个十六进制值,然后排序并计数:

od -t x1 -w1 -v -An mybinaryfile | sort | uniq -c

(-w1是一个扩展,它不是由POSIX.)

答案2

使用 Perl 将 slurped 文件解压为字节数组,然后使用哈希来计算唯一字节数:

printf '\xA0\x01\x00\xFF\x77\x01\x77\x01\xA0' | 
  perl -0777 -nE '
    @bytes = unpack("C*",$_) 
    }{ 
    $counts{$_}++ for @bytes; 
    for $k (sort { $a <=> $b } keys %counts) {
      printf "%02X: %d\n", $k, $counts{$k}
    }
 '
00: 1
01: 3
77: 2
A0: 2
FF: 1

如果有足够新的版本List::MoreUtils可用,您也许可以使用其frequency功能来简化计数。

答案3

快速Python解决方案:

#!/usr/bin/env python3
import sys, itertools, collections
print(
    *itertools.starmap(
        "{:02X}: {:d}".format,
        collections.Counter(sys.stdin.detach().read()).items()),
    sep="\n")

单线:

python3 -c 'import sys, itertools, collections; print(*itertools.starmap("{:02X}: {:d}".format, collections.Counter(sys.stdin.detach().read()).items()), sep="\n")' \
    < input.bin

选项和注意事项

  • 如果您希望输出按频率降序排序,请替换.items().most_common()。或者,对于其他排序方案,请使用内置的sorted()函数或使用后处理输出sort(1)程序。

  • 在当前状态下,程序将整个标准输入数据放入字节缓冲区中,这对于相对较小的文件来说很好。对于较大的文件,需要将程序重写为分块读取文件

答案4

如果文件很大,您可以边计算边排序

od -t x1 -w1 -v -An binaryfile |
    awk '{h[$1]++} END {for (v in h) {printf "%d\t%s\n", h[v], v} }' |
    sort -k2

如果您需要 POSIX 解决方案

od -t x1 -v -An binaryfile |
    tr ' ' '\n' |
    awk '$1 > "" { h[$1]++ } END { for (v in h) {printf "%d\t%s\n", h[v], v} }' |
    sort -k2

相关内容