Sortieren Sie die Zeilen nach der Anzahl der Wörter pro Zeile

14

Vorgegebene Eingabe:

hello: world foo bar baz
bar:
baz: bin boop bop fiz bang beep
bap: bim bam bop
boatkeeper: poughkeepsie

Ich würde es gerne in die meisten Wörter oben sortieren, am Ende zumindest so:

baz: bin boop bop fiz bang beep
hello: world foo bar baz
bap: bim bam bop
boatkeeper: poughkeepsie
bar:

Wie würde ich das mit sorteinem anderen Tool machen?

Caleb Xu
quelle
Um es klar auszudrücken, möchten Sie nach der Anzahl der Wörter und nicht nach der Zeilenlänge sortieren (bei Ihrer Beispieleingabe ist die Zeile mit den meisten Wörtern auch die längste, aber das ist möglicherweise nicht immer der Fall)?
don_crissti
Ja. Die Zeile mit den meisten Wörtern ist im Allgemeinen nicht unbedingt die längste. zB will ich bin: bop boopvorher boatkeeper: poughkeepsie. Wenn zwei Zeilen die gleiche Anzahl von Wörtern enthalten, wäre es mir lieber, wenn die Verknüpfungen alphabetisch sortiert wären, aber das ist keine Voraussetzung.
Caleb Xu

Antworten:

22

Sie könnten etwas tun wie:

awk '{print NF,$0}' file | sort -nr | cut -d' ' -f 2-

Wir verwenden, awkum die Anzahl der Felder jeder Zeile voranzustellen. Wir geben dann sortdiese Nummer ein und entfernen sie mit cut.

Dunkles Herz
quelle
Das hat funktioniert. Ich habe mich gefragt, warum die Reihenfolge umgekehrt wurde, aber ich sehe Ihre Änderung jetzt.
Caleb Xu
6

In neueren GNU- awkVersionen kann man PROCINFOArray verwenden, um viele interne Parameter zu definieren, einschließlich der Reihenfolge, in der Array-Elemente gedruckt werden (gesteuert durch Element "sorted_in"). Somit können wir mit dem Wert von NF" "NR, welche Elemente den Wert von haben , ein Array erstellen und indizieren $0und es in der gewünschten Ausgabe ausgeben, in Ihrem Fall wäre das "@ind_num_desc":

awk '{a[NF" "NR]=$0}END{PROCINFO["sorted_in"]="@ind_num_desc"; for(i in a) print a[i]}' file
jimmij
quelle
1
+1 dachte das Gleiche: Man sollte jedoch beachten, dass es den Nebeneffekt hat, die Eingabe zu duplizieren
steeldriver
@steeldriver du bist absolut korrekt, ich habe meine Antwort bearbeitet, sollte jetzt in Ordnung sein.
Jimmy
Dadurch bleibt die ursprüngliche Reihenfolge zwischen Datensätzen mit der gleichen Anzahl von Feldern erhalten, anstatt die Wörter als sekundären Sortierschlüssel zu sortieren. Wenn Ihre Schlüssel vorhanden wären NF" "$0" "NR, hätten Sie nur NReinen Fallback- / Duplikatbehandlungsmechanismus.
Peter Cordes
1
@ PeterCordes, aber das würde die Reihenfolge der Wörter umkehren, ich sehe keine Möglichkeit, Verbindungen alphabetisch zu lösen, die nicht per Definition eigene Funktion cmp_func()- Gnu awk erlaubt das.
Jimmy
5

Perl Einzeiler:

print sort { split(' ',$a) <=> split(' ',$b) } <>;

Wenn Sie Verbindungen in alphabetischer Reihenfolge trennen möchten:

print sort { split(' ',$a) <=> split(' ',$b) or $a cmp $b } <>;
Nate Eldredge
quelle
4

Durch Python.

s = '''hello: world foo bar baz
bar:
baz: bin boop bop fiz bang beep
bap: bim bam bop'''.splitlines()
for i in sorted(s, key=lambda x: len(x.split()), reverse=True):
    print(i)

oder

with open('/path/to/the/input/file') as f:
    m = f.readlines()
    for i in sorted(m, key=lambda x: len(x.split()), reverse=True):
        print(i, end="")
Avinash Raj
quelle