Ich habe 100 Millionen Zeilen in meiner Datei.
Jede Zeile hat nur eine Spalte.
z.B
aaaaa
bb
cc
ddddddd
ee
Ich möchte die Anzahl der Zeichen auflisten
So was
2 character words - 3
5 character words - 1
7 character words - 1
usw.
Gibt es eine einfache Möglichkeit, dies im Terminal zu tun?
text-processing
Giri
quelle
quelle
Antworten:
Der erste
awk
Filter druckt nur die Länge jeder Zeile in der aufgerufenen Dateifile
. Ich gehe davon aus, dass diese Datei ein Wort pro Zeile enthält.Mit
sort -n
(Sortieren der Zeilen aus der Ausgabe vonawk
numerisch in aufsteigender Reihenfolge) unduniq -c
(Zählen der Häufigkeit, mit der jede Zeile nacheinander auftritt) wird dann die folgende Ausgabe für die angegebenen Daten erstellt:Dies wird dann durch das zweite
awk
Skript analysiert, das jede Zeile als "X Anzahl von Zeilen mit Y Zeichen" interpretiert und die gewünschte Ausgabe erzeugt.Die alternative Lösung besteht darin, alles
awk
in einem Array zu erledigen und die Anzahl der Längen beizubehalten. Es ist ein Kompromiss zwischen Effizienz, Lesbarkeit / Verständlichkeit (und damit Wartbarkeit), welche Lösung die "beste" ist.Alternative Lösung:
quelle
Ein anderer Weg, alles
awk
alleine zu machenwords[length()]++
Verwenden Sie die Länge der Eingabezeile als Schlüssel, um die Anzahl zu speichernEND{for(k in words)print k " character words - " words[k]}
Nachdem alle Zeilen verarbeitet wurden, drucken Sie den Inhalt des Arrays im gewünschten FormatLeistungsvergleich, ausgewählte Zahlen sind am besten aus zwei Läufen
Wenn die Datei nur ASCII-Zeichen enthält,
Ich bin mir nicht sicher, warum sich die Zeit für
perl
nicht viel geändert hat. Wahrscheinlich muss die Codierung anders eingestellt werdenquelle
length
ohne()
funktioniert hier einwandfrei, so dass es möglicherweise überflüssig ist, geschweifte Klammern hinzuzufügen. Ich benutze jedoch GNU awk.In older versions of awk, the length() function could be called without any parentheses. Doing so is considered poor practice, although the 2008 POSIX standard explicitly allows it, to support historical practice. For programs to be maximally portable, always supply the parentheses
Hier ist ein
perl
Äquivalent (mit - optional - sort):quelle
{$a<=>$b}
nach demsort
würde das beheben. Alternativ könnte man ein normales Array mit numerischen Schlüsseln verwenden und einfach alle Schlüssel überspringen, bei denen der Wert Null / undefiniert ist.Eine Alternative ein Aufruf an GNU awk, mit printf :
Der Kernalgorithmus sammelt nur die Anzahl der Zeichen in einem Array. Der Endteil druckt die mit printf formatierten gesammelten Zählungen.
Schnell, einfach, ein einziger Anruf bei awk.
Um genau zu sein: Es wird etwas mehr Speicher verwendet, um das Array zu behalten.
Es wird jedoch keine Sortierung aufgerufen (numerische Array-Indizes werden so eingestellt, dass sie mit PROCINFO immer nach oben sortiert durchlaufen werden), und nur ein externes Programm:
awk
anstelle mehrerer.quelle
for in
Es kann vorkommen, dass numerische Array-Indizes zumindest für einige Werte oder in einigen awk-Implementierungen in numerischer Reihenfolge angegeben werden. Dies ist jedoch nicht erforderlich, nicht traditionell und definitiv nicht universell. Es kommt oft bei winzigen Sets wie 2 oder 3 oder vielleicht 4 vor; Versuchen Sie 10 oder 20 bei jeder Woche, auf die Sie Zugriff haben (ohne PROCINFO oder WHINY_USERS in gawk), und ich wette, dass mindestens ein Fall nicht sortiert ist.@ind_str_asc
sortiert als Zeichenfolgen, die für Zahlen nur dann korrekt sind, wenn sie alle einstellig sind (wie in Ihrem Beispiel); Verwenden Sie@ind_num_asc
diese Option, wenn (beliebige) Werte 10 oder mehr betragen können. Und obwohl es heute weniger ein Problem ist als früher, ist diese Funktion nur ab Version 4.0 verfügbar .