Antworten:
Folgendes sollte funktionieren:
$ sed 's/\(.\)/\1\n/g' text.txt | sort | uniq -c
Zuerst fügen wir nach jedem Zeichen eine neue Zeile ein, wobei jedes Zeichen in eine eigene Zeile gesetzt wird. Dann sortieren wir es. Dann verwenden wir den Befehl uniq, um die Duplikate zu entfernen, wobei jeder Zeile die Anzahl der Vorkommen dieses Zeichens vorangestellt wird.
Um die Liste nach Häufigkeit zu sortieren, leiten Sie dies alles in sort -nr
.
sed
tun, aber die Python-Lösung von Jacob Vlijm hat für mich gut funktioniert.
Stevens Lösung ist gut und einfach. Bei sehr großen Dateien (Dateien, die nicht in die Hälfte des Arbeitsspeichers passen) ist die Leistung aufgrund des Sortierschritts nicht so hoch. Hier ist eine awk-Version. Es ist auch ein wenig komplizierter , weil es versucht , das Richtige für ein paar Sonderzeichen (Zeilenumbrüche, zu tun '
, \
, :
).
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/:/'
Hier ist eine Perl-Lösung nach dem gleichen Prinzip. Perl hat den Vorteil, intern sortieren zu können. Dies wird auch eine zusätzliche Newline nicht korrekt zählen, wenn die Datei nicht mit einem Newline-Zeichen endet.
perl -ne '
++$c{$_} foreach split //;
END { printf "'\''%s'\'': %d\n", /[\\'\'']/ ? "\\$_" : /./ ? $_ : "\\n", $c{$_}
foreach (sort {$c{$b} <=> $c{$a}} keys %c) }'
Eine langsame, aber relativ speicherfreundliche Version mit Ruby. Ungefähr ein Dutzend MB RAM, unabhängig von der Eingabegröße.
# 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