Yanıtlar:
Aşağıdakiler işe yaramalıdır:
$ sed 's/\(.\)/\1\n/g' text.txt | sort | uniq -c
İlk olarak, her karakterden sonra yeni bir satır ekleyerek her karakteri kendi satırına koyarız. Sonra sıralarız. Ardından, her satıra o karakterin yineleme sayısını ekleyerek yinelemeleri kaldırmak için uniq komutunu kullanırız.
Listeyi frekansa göre sıralamak için, bunların tümünü boruya ekleyin sort -nr
.
sed
, ama Jacob Vlijm'in Python çözümü benim için iyi çalıştı.
Steven'ın çözümü iyi, basit bir çözümdür. Sıralama aşaması nedeniyle çok büyük dosyalar (RAM'inizin yarısına rahatça sığmayan dosyalar) için çok performanssızdır. İşte bir awk versiyonu. Bu bir kaç özel karakterler için doğru olanı yapmaya çalışır çünkü karmaşık da biraz daha yüksek (yeni satırlar, '
, \
, :
).
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/:/'
İşte aynı prensipte bir Perl çözümü. Perl dahili olarak sıralama yapabilme avantajına sahiptir. Ayrıca, dosya yeni satır karakteri ile bitmezse, bu durum fazladan yeni bir satır saymaz.
perl -ne '
++$c{$_} foreach split //;
END { printf "'\''%s'\'': %d\n", /[\\'\'']/ ? "\\$_" : /./ ? $_ : "\\n", $c{$_}
foreach (sort {$c{$b} <=> $c{$a}} keys %c) }'
Ruby kullanan yavaş ama nispeten bellek dostu bir sürüm. Giriş boyutundan bağımsız olarak yaklaşık bir düzine MB 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
sed 's/\(.\)/\1\'$'\n/g' text.txt