เรียงลำดับบรรทัดตามจำนวนคำต่อบรรทัด


14

รับอินพุต:

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

ฉันต้องการเรียงลำดับเป็นคำส่วนใหญ่ที่ด้านบนสุดไปจนถึงท้ายที่สุดเช่น:

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

ฉันจะทำสิ่งนี้กับsortเครื่องมืออื่น ๆ ได้อย่างไร?


เพื่อให้ชัดเจนคุณต้องการจัดเรียงตามจำนวนคำที่ไม่เรียงตามความยาวบรรทัด (ด้วยการป้อนตัวอย่างของคุณบรรทัดที่มีคำส่วนใหญ่ก็ยาวที่สุด แต่นั่นอาจไม่ใช่กรณี)
don_crissti

ใช่. บรรทัดที่มีคำส่วนใหญ่ไม่จำเป็นต้องยาวที่สุดโดยทั่วไป เช่นฉันต้องการก่อนbin: bop boop boatkeeper: poughkeepsieหากสองบรรทัดมีจำนวนคำเท่ากันฉันอยากจะให้ความสัมพันธ์นั้นเป็นตัวอักษร แต่นั่นไม่ใช่ข้อกำหนด
Caleb Xu

คำตอบ:


22

คุณสามารถทำสิ่งที่ชอบ:

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

เราใช้awkคำนำหน้าจำนวนฟิลด์ไปยังแต่ละบรรทัด จากนั้นเราจะจากจำนวนที่และลบมันด้วยsortcut


สิ่งนี้ใช้ได้ผล กำลังสงสัยว่าทำไมคำสั่งซื้อถูกกลับรายการ แต่ฉันเห็นการแก้ไขของคุณตอนนี้
Caleb Xu

6

ใน GNU เมื่อเร็ว ๆ นี้awkเราสามารถใช้PROCINFOอาร์เรย์เพื่อกำหนดพารามิเตอร์ภายในจำนวนมากรวมถึงลำดับที่องค์ประกอบอาร์เรย์จะถูกพิมพ์ (ควบคุมโดยองค์ประกอบ"sorted_in") ดังนั้นเราสามารถสร้างและจัดทำดัชนีอาร์เรย์ด้วยค่าของNF" "NRองค์ประกอบที่มีมูลค่า$0และพิมพ์ในผลลัพธ์ที่ต้องการในกรณีของคุณที่จะ"@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 กำลังคิดในสิ่งเดียวกัน: อย่างไรก็ตามเราควรทราบว่ามันจะมีผลข้างเคียงของการทำซ้ำอินพุต
ขับเหล็ก

@steeldriver คุณถูกต้องแน่นอนฉันได้แก้ไขคำตอบของฉันควรจะดีตอนนี้
jimmij

ตอนนี้จะรักษาลำดับเดิมระหว่างเร็กคอร์ดที่มีจำนวนฟิลด์เท่ากันแทนที่จะเรียงลำดับคำเป็นคีย์การเรียงลำดับรอง หากกุญแจของคุณคือNF" "$0" "NRคุณจะมีเพียงNRกลไกทางเลือก / การจัดการซ้ำ
ปีเตอร์กอร์เดส

1
@ PeterCordes แต่ที่จะย้อนกลับลำดับของคำฉันไม่เห็นวิธีการแก้ไขความสัมพันธ์ตามลำดับตัวอักษรอื่น ๆ ที่ฟังก์ชั่นของตัวเองนิยามcmp_func()- gnu awk ช่วยให้ที่
jimmij

5

Perl หนึ่งซับ:

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

หากคุณต้องการที่จะทำลายความสัมพันธ์โดยใช้ลำดับตัวอักษร:

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

4

ผ่านหลาม

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)

หรือ

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="")
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.