Urutkan baris berdasarkan jumlah kata per baris

14

Masukan yang diberikan:

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

Saya ingin mengurutkannya menjadi sebagian besar kata di bagian atas, paling tidak di akhir, seperti:

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

Bagaimana saya melakukan ini dengan sortatau alat lain?

Caleb Xu
sumber
Untuk lebih jelasnya, Anda ingin mengurutkan berdasarkan jumlah kata, bukan mengurutkan berdasarkan panjang baris (dengan input sampel, baris dengan kata terbanyak juga paling panjang tetapi mungkin tidak selalu demikian)?
don_crissti
Iya. Garis dengan kata-kata terbanyak belum tentu terpanjang pada umumnya. misalnya saya mau bin: bop boopsebelumnya boatkeeper: poughkeepsie. Jika dua baris memiliki jumlah kata yang sama, saya lebih suka ikatannya diurutkan menurut abjad, tapi itu bukan keharusan.
Caleb Xu

Jawaban:

22

Anda dapat melakukan sesuatu seperti:

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

Kami menggunakan awkuntuk mengawali jumlah bidang untuk setiap baris. Kami kemudian sortdengan nomor itu dan menghapusnya dengan cut.

Hati gelap
sumber
Ini berhasil. Ingin tahu mengapa pesanan dibatalkan, tetapi saya melihat hasil edit Anda sekarang.
Caleb Xu
6

Dalam GNU baru-baru ini awkseseorang dapat menggunakan PROCINFOarray untuk mendefinisikan banyak parameter internal termasuk urutan di mana elemen array dicetak (dikontrol oleh elemen "sorted_in"). Dengan demikian kita dapat membangun dan menyusun indeks dengan nilai NF" "NR, elemen mana yang memiliki nilai $0dan mencetaknya dalam output yang diinginkan, dalam kasus Anda yaitu "@ind_num_desc":

awk '{a[NF" "NR]=$0}END{PROCINFO["sorted_in"]="@ind_num_desc"; for(i in a) print a[i]}' file
jimmij
sumber
1
+1 memikirkan hal yang sama: namun orang mungkin harus mencatat bahwa itu akan memiliki efek samping dari menduplikasi input
steeldriver
@steeldriver Anda benar sekali, saya mengedit jawaban saya, harus baik-baik saja sekarang.
jimmij
Ini sekarang mempertahankan urutan asli antara catatan dengan jumlah bidang yang sama, alih-alih mengurutkan kata-kata sebagai kunci pengurutan sekunder. Jika kunci NF" "$0" "NRAnda, Anda hanya akan memiliki NRmekanisme penanganan mundur / duplikat.
Peter Cordes
1
@PeterCordes tapi itu akan membalik urutan kata-kata, saya tidak melihat cara untuk menyelesaikan ikatan abjad lainnya yang menurut definisi fungsi sendiri cmp_func()- gnu awk memungkinkan itu.
jimmij
5

Perl one-liner:

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

Jika Anda ingin memutuskan hubungan menggunakan urutan alfabet:

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

Melalui 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)

atau

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
sumber