ファイルの固有文字数を出力するプログラムが必要です。例:
> stats testfile
' ': 207
'e': 186
'n': 102
これを行うツールはありますか?
答え1
次は動作します。
$ sed 's/\(.\)/\1\n/g' text.txt | sort | uniq -c
まず、各文字の後に改行文字を挿入して、各文字を独自の行に配置します。それからソートしてみましょう。次に uniq コマンドを使用して重複を削除し、各行の前にその文字の発生回数を追加します。
頻度でリストを並べ替えるには、すべての項目をsort -nr
。
答え2
Stevenのソリューションは、素晴らしいとシンプルなソリューションです。ソートフェーズのため、非常に大きなファイル(RAMの約半分に簡単に入ることができないファイル)では正しく実行されません。これはawkバージョンです。また、'
一部の特殊文字(改行文字、、、、)を使用して正しい操作を実行しようとしているため、少し複雑です。\
:
awk '
{for (i=1; i<=length; i++) ++c[substr($0,i,1)]; ++c[RS]}
function chr (x) {return x=="\n" ? "\\n" : x==":" ? "\\072" :
x=="\\" || x=="'\''" ? "\\" x : x}
END {for (x in c) printf "'\''%s'\'': %d\n", chr(x), c[x]}
' | sort -t : -k 2 -r | sed 's/\\072/:/'
これは同じ原理に基づくPerlソリューションです。 Perlの利点は内部整列機能です。また、ファイルが改行で終わらないと、追加の改行が正しく計算されません。
perl -ne '
++$c{$_} foreach split //;
END { printf "'\''%s'\'': %d\n", /[\\'\'']/ ? "\\$_" : /./ ? $_ : "\\n", $c{$_}
foreach (sort {$c{$b} <=> $c{$a}} keys %c) }'
答え3
Rubyを使用するのは遅いが比較的メモリに優しいバージョンです。入力サイズに関係なく、約12MBのRAMです。
# count.rb
ARGF.
each_char.
each_with_object({}) {|e,a| a[e] ||= 0; a[e] += 1}.
each {|i| puts i.join("\t")}
ruby count.rb < input.txt
t 20721
d 20628
S 20844
k 20930
h 20783
... etc
答え4
シンプルで比較的パフォーマンスが良いです。
fold -c1 testfile.txt | sort | uniq -c
fold
1文字ごとに改行(たとえば改行を挿入)するように指示します。
テスト方法:
- 128MBフルASCIIファイル
find . -type f -name '*.[hc]' -exec cat {} >> /tmp/big.txt \;
いくつかのコードベースで生成されました。
- ワークステーション級マシン(仮想マシンではなく実際の鉄)
- 環境変数
LC_ALL=C
降順で実行時間:
- スティーブンの
sed|sort|uniq
ソリューション(https://unix.stackexchange.com/a/5011/427210):102.5秒 - 私の
fold|sort|uniq
ソリューション:59.3秒 - オプションを含む私の
fold|sort|uniq
ソリューション:38.9秒--buffer-size=12G
sort
- 私の
fold|sort|uniq
解決策、与えられたオプション--buffer-size=12G
:37.9秒--stable
sort
- Gilesの
perl
ソリューション(https://unix.stackexchange.com/a/5013/427210):34.0秒- 勝者!彼らが言ったように、最も速いソートは並べ替える必要はありません。。
:-)
- 勝者!彼らが言ったように、最も速いソートは並べ替える必要はありません。。