例:「mybinaryfile」ファイルがあり、16進数の内容は次のとおりです。
A0 01 00 FF 77 01 77 01 A0
このファイルにA0バイトがいくつあるのか、01がいくつあるのかなどを知る必要があります。結果は次のとおりです。
A0: 2
01: 3
00: 1
FF: 1
77: 2
シェルで直接計算を実行する方法はありますか?または、この特定のタスクを実行するには、どの言語でプログラムを作成する必要がありますか?
答え1
答え2
Perlを使用してスラッピングされたファイルをバイト配列に解凍し、ハッシュを使用して一意のバイト数を計算します。
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")
1本のライン:
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