Kar*_*ter 13 command-line statistics binary files
我想知道相当于
cat inputfile | sed 's/\(.\)/\1\n/g' | sort | uniq -c
Run Code Online (Sandbox Code Playgroud)
在/sf/ask/292187941/ 中提出,用于在文本文件中生成用于二进制文件计数的字符使用统计信息简单的字节而不是字符,即输出应为
18383 57
12543 44
11555 127
8393 0
Run Code Online (Sandbox Code Playgroud)
命令是否与引用的字符一样长并不重要。
如果我将字符命令应用于二进制文件,则输出包含不可打印字符的任意长序列的统计信息(我不寻求解释)。
使用 GNU od:
od -vtu1 -An -w1 my.file | sort -n | uniq -c
Run Code Online (Sandbox Code Playgroud)
或者更有效地使用perl(还为不发生的字节输出计数(0)):
perl -ne 'BEGIN{$/ = \4096};
$c[$_]++ for unpack("C*");
END{for ($i=0;$i<256;$i++) {
printf "%3d: %d\n", $i, $c[$i]}}' my.file
Run Code Online (Sandbox Code Playgroud)
对于大文件,使用 sort 会很慢。我编写了一个简短的 C 程序来解决等效的问题(请参阅带有测试的 Makefile 的要点):
#include <stdio.h>
#define BUFFERLEN 4096
int main(){
// This program reads standard input and calculate frequencies of different
// bytes and present the frequences for each byte value upon exit.
//
// Example:
//
// $ echo "Hello world" | ./a.out
//
// Copyright (c) 2015 Björn Dahlgren
// Open source: MIT License
long long tot = 0; // long long guaranteed to be 64 bits i.e. 16 exabyte
long long n[256]; // One byte == 8 bits => 256 unique bytes
const int bufferlen = BUFFERLEN;
char buffer[BUFFERLEN];
int i;
size_t nread;
for (i=0; i<256; ++i)
n[i] = 0;
do {
nread = fread(buffer, 1, bufferlen, stdin);
for (i = 0; i < nread; ++i)
++n[(unsigned char)buffer[i]];
tot += nread;
} while (nread == bufferlen);
// here you may want to inspect ferror of feof
for (i=0; i<256; ++i){
printf("%d ", i);
printf("%f\n", n[i]/(float)tot);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
用法:
gcc main.c
cat my.file | ./a.out
Run Code Online (Sandbox Code Playgroud)