Ordina le righe per numero di parole per riga


14

Dato input:

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

Vorrei ordinarlo in gran parte delle parole in alto, almeno alla fine, in questo modo:

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

Come lo farei con sorto con qualche altro strumento?


Per essere chiari, vuoi ordinare per numero di parole non per lunghezza della linea (con il tuo esempio di input la linea con il maggior numero di parole è anche la più lunga ma potrebbe non essere sempre così)?
don_crissti,

Sì. La linea con il maggior numero di parole non è necessariamente la più lunga in generale. ad esempio, voglio bin: bop boopprima boatkeeper: poughkeepsie. Se due righe condividono lo stesso numero di parole, preferirei che i legami fossero in ordine alfabetico, ma non è un requisito.
Caleb Xu,

Risposte:


22

Potresti fare qualcosa del tipo:

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

Usiamo awkcome prefisso il numero di campi per ogni riga. Abbiamo quindi sortquel numero e lo rimuoviamo con cut.


Questo ha funzionato. Mi chiedevo perché l'ordine fosse invertito, ma ora vedo la tua modifica.
Caleb Xu,

6

Nella recente GNU awksi può usare l' PROCINFOarray per definire molti parametri interni incluso l'ordine in cui gli elementi dell'array sono stampati (controllati dall'elemento "sorted_in"). Quindi possiamo costruire e array indicizzati con il valore di NF" "NR, quali elementi hanno valore di $0e stamparlo nell'output desiderato, nel tuo caso sarebbe "@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 stava pensando la stessa cosa: tuttavia si dovrebbe forse notare che avrà l'effetto collaterale di de-duplicare l'input
steeldriver

@steeldriver hai perfettamente ragione, ho modificato la mia risposta, ora dovrebbe andare bene.
Jimmij,

Ciò ora preserva l'ordinamento originale tra i record con lo stesso numero di campi, invece di ordinare le parole come chiave di ordinamento secondaria. Se le tue chiavi fossero NF" "$0" "NR, avresti solo NRun meccanismo di fallback / gestione dei duplicati.
Peter Cordes,

1
@PeterCordes ma ciò rovescerebbe l'ordine delle parole, non vedo alcun modo di risolvere alfabeticamente i legami se non per definizione la propria funzione cmp_func()- gnu awk lo consente.
Jimmij,

5

Perl one-liner:

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

Se vuoi rompere i legami usando l'ordine alfabetico:

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

4

Attraverso il pitone.

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)

o

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="")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.