Satırları satır başına kelime sayısına göre sırala


14

Verilen girdi:

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

Bunu en üstte, en azından sonunda, en çok şu şekilde sıralamak istiyorum:

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

Bunu sortbaşka bir araçla nasıl yapabilirim ?


Açık olmak gerekirse, satır uzunluğuna göre sıralanmayan kelime sayısına göre sıralamak istersiniz (örnek girişinizle en çok kelimeye sahip satır da en uzundur, ancak bu her zaman böyle olmayabilir)?
don_crissti

Evet. En çok kelimeyi içeren çizgi, genel olarak en uzun kelime olmak zorunda değildir. örneğin, daha bin: bop boopönce istiyorum boatkeeper: poughkeepsie. İki satır aynı sayıda kelimeyi paylaşıyorsa, bağların alfabetik olmasını tercih ederim, ancak bu bir gereklilik değildir.
Caleb Xu

Yanıtlar:


22

Şöyle bir şey yapabilirsiniz:

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

awkHer satıra alan sayısını önek olarak kullanırız . Sonra sortbu numaraya göre kaldırırız cut.


Bu işe yaradı. Siparişin neden tersine çevrildiğini merak ediyordum, ancak şimdi düzenlemenizi görüyorum.
Caleb Xu

6

Son GNU'da awk, PROCINFOdizi öğelerinin yazdırılma sırası (öğe tarafından kontrol edilir "sorted_in") dahil olmak üzere birçok dahili parametreyi tanımlamak için dizi kullanılabilir . Böylece NF" "NR, hangi öğelerin değerine sahip $0olduğu ve istenen çıktıda yazdıracağınız değerle indekslenebilir ve diziniz olabilir "@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 aynı şeyi düşünüyordu: Bununla birlikte, girişin çoğaltılmasının yan etkisine sahip olacağına dikkat edilmelidir
steeldriver

@steeldriver kesinlikle haklısın, cevabımı düzenledim, şimdi iyi olmalı.
jimmij

Bu, şimdi kelimeleri ikincil bir sıralama anahtarı olarak sıralamak yerine, aynı sayıda alana sahip kayıtlar arasındaki orijinal sıralamayı korur. Anahtarlarınız NF" "$0" "NRolsaydı, yalnızca NRbir geri dönüş / çoğaltma işleme mekanizması olarak olurdu .
Peter Cordes

1
@PeterCordes ama kelimelerin sırasını tersine çevirir, tanımları kendi işlevi ile alfabetik olarak çözmek için hiçbir yol görmüyorum cmp_func()- gnu awk buna izin verir.
jimmij

5

Perl tek katmanlı:

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

Alfabetik sırayla bağları koparmak istiyorsanız:

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

4

Python ile.

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)

veya

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="")
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.