示例:我有文件“mybinaryfile”,十六进制内容为:
A0 01 00 FF 77 01 77 01 A0
我需要知道这个文件中有多少个A0字节,有多少个01等等。结果可能是:
A0: 2
01: 3
00: 1
FF: 1
77: 2
有没有什么方法可以直接在 shell 中进行计数,或者我是否需要用任何语言编写一个程序来完成这个特定的任务?
答案1
答案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