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?


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.


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

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 } <>;

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="")
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.