แสดงรายการไฟล์ที่เรียงตามจำนวนบรรทัดที่มี


32

ฉันจะแสดงรายการจำนวนบรรทัดในไฟล์/group/book/four/wordเรียงลำดับตามจำนวนบรรทัดที่มีได้อย่างไร

ls -l คำสั่งรายการพวกเขาลง แต่ไม่ได้จัดเรียงพวกเขา


1
คุณต้องการไฟล์ที่แสดงตามจำนวนบรรทัดหรือรายการจำนวนบรรทัดในไฟล์หรือทั้งสองอย่าง? ls -lไม่ได้ให้จำนวนบรรทัด ls -lSเรียงลำดับไฟล์ตามขนาดด้วยlsการนำไปใช้งานบางอย่าง( ขนาดเป็นจำนวนไบต์ในเนื้อหา)
Stéphane Chazelas

คำตอบ:


34

คุณควรใช้คำสั่งเช่นนี้:

find /group/book/four/word/ -type f -exec wc -l {} + | sort -rn
  • find: ค้นหาไฟล์บนเส้นทางที่คุณต้องการ หากคุณไม่ต้องการให้เกิดขึ้นซ้ำและfindการใช้งานของคุณรองรับคุณควรเพิ่ม-maxdepth 1ก่อน-execตัวเลือก
  • exec: บอกให้คำสั่งดำเนินการwc -lทุกไฟล์
  • sort -rn: จัดเรียงผลลัพธ์เป็นตัวเลขในลำดับย้อนกลับ จากมากไปน้อย

(สมมติว่าชื่อไฟล์ไม่มีอักขระขึ้นบรรทัดใหม่)


โปรดทราบว่าเมื่อส่งมากกว่าหนึ่งไฟล์ (หรือมีการใช้งานบางอย่างมากกว่าหนึ่งไฟล์ที่สามารถอ่านได้) wcจะพิมพ์totalบรรทัดดังนั้นที่นี่คุณจะได้รับหนึ่งบรรทัด "รวม" เว้นแต่ว่ามีไฟล์เดียวเท่านั้น . คุณสามารถไปที่grep /เพื่อลบ
Stéphane Chazelas

โหวตขึ้นเนื่องจากsortคำสั่ง
Francisco

ฉันจะกรองเพื่อแสดงเฉพาะไฟล์ที่มี X บรรทัดต่ำสุดได้อย่างไร (ยกเว้น X = 0 บรรทัดสำหรับตัวอย่าง)
เมทริกซ์

11

Non-recursive

อาจเป็นเวอร์ชั่นที่ง่ายที่สุดถ้าคุณไม่ต้องการ recursivity:

wc -l /group/book/four/word/*|sort -n

wcนับบรรทัด (ตัวเลือก-l) ในทุก ๆ ไฟล์ (แต่ซ่อนอยู่) ( *) /group/book/four/word/และsortเรียงลำดับผลลัพธ์ (ผ่านไปป์|) เป็นตัวเลข (ตัวเลือก-n)

ซ้ำ

มีคนแสดงความคิดเห็นกับคำตอบที่กล่าวถึงgrep -rlcนี้ก่อนที่จะระงับ แน่นอนgrepเป็นทางเลือกที่ดีโดยเฉพาะอย่างยิ่งถ้าคุณต้องการ recursivity:

grep -rc '^' /group/book/four/word/|tr ':' ' '|sort -n -k2

จะนับ (ตัวเลือก-c) ซ้ำ (ตัวเลือก-r) สายการจับคู่ ( grep) '^'(นั่นคือจุดเริ่มต้นของเส้น) /group/book/four/word/ในไดเรกทอรี จากนั้นคุณต้องแทนที่โคลอนด้วยช่องว่างเช่นใช้trเพื่อช่วยsortซึ่งคุณต้องการเรียงลำดับตัวเลข (ตัวเลือก-n) ในคอลัมน์ที่สอง (ตัวเลือก-k2)

อัปเดต:ดูความคิดเห็นของสเตฟานเกี่ยวกับข้อ จำกัด ที่เป็นไปได้และวิธีกำจัดของtrจริง


3
grep -c .นับบรรทัดที่มีอักขระที่ถูกต้องอย่างน้อยหนึ่งตัว ใช้grep -c '^'เพื่อนับบรรทัดทั้งหมด (จะนับจำนวนอักขระต่อท้ายหลังขึ้นบรรทัดใหม่ด้วยgrepการปรับใช้บางอย่าง) โปรดทราบว่าgrepการใช้งานไม่ได้ทั้งหมดสนับสนุน-rและพฤติกรรมที่แตกต่างกันไปในหมู่ที่ทำ คุณไม่จำเป็นต้องแปล:s (ลำไส้ใหญ่ไม่อัฒภาค) sortไปที่ช่องว่างสำหรับ -t:ใช้เพียงแค่ โปรดทราบว่าสันนิษฐานว่าชื่อไฟล์ไม่มี:หรือเว้นว่างหรือขึ้นบรรทัดใหม่
Stéphane Chazelas

1
ขอขอบคุณที่โพสต์โซลูชันที่ไม่เรียกซ้ำ ฉันไม่ทราบว่าwcให้ผลรวมที่มีประโยชน์ทั้งหมดถ้าคุณผ่านหลายเส้นทาง การเชื่อมต่อการทำงานนั้นกับ wild card และไปป์ที่sortสะอาดจริงๆ
Qcom

7

ด้วยzsh:

lines() REPLY=$(wc -l < $REPLY)
printf '%s\n' /group/book/four/word/*(.no+lines)

เรากำหนดฟังก์ชันการเรียงลำดับใหม่linesที่ตอบกลับด้วยจำนวนบรรทัดในไฟล์ และเราใช้ตัวระบุแบบo+linesกลมซึ่งรวมกับn(สำหรับการเรียงลำดับแบบตัวเลข) กำหนดวิธีการเรียงลำดับผลลัพธ์ของแบบกลม ( .เพิ่มเพื่อตรวจสอบไฟล์ปกติเท่านั้น)

ทำให้ไม่มีการสันนิษฐานว่าอักขระชื่อไฟล์อาจมีอะไรนอกเหนือจากไฟล์ที่ซ่อนอยู่ (ที่ขึ้นต้นด้วย.) จะถูกละเว้น เพิ่มตัวระบุDรอบตัวถ้าคุณต้องการเช่นกัน


2
OP ถูกติดแท็กด้วยbashเท่านั้น ...
l0b0

7
@ l0b0 ที่ไม่ได้หมายความว่าบุคคลต่อไปที่ต้องการสิ่งนี้จะใช้ bash เช่นกัน
terdon

4

คุณไม่ได้ระบุว่าคุณต้องการไฟล์ในไดเรกทอรีย่อย/group/book/four/wordหรือไม่ การfindแก้ปัญหาในคำตอบของ jherran จะลงไปในไดเรกทอรีย่อย หากไม่ต้องการใช้เชลล์แทน:

for file in ./*; do [ -f "$file" ] && wc -l "$file"; done | sort -n

หากชื่อไฟล์ของคุณมีบรรทัดใหม่คุณสามารถใช้สิ่งต่อไปนี้:

for file in ./*; do 
    [ -f "$file" ] && 
        printf "%lu %s\0" "$(wc -l < "$file")" "$file"
done | sort -zn | tr '\0' '\n'

สุดท้ายหากคุณทำลงไปลงในไดเรกทอรีย่อยคุณสามารถใช้ในbash4 หรือสูงกว่า:

shopt -s globstar
for file in ./**/*; do [ -f "$file" ] && wc -l "$file"; done | sort -n

โปรดทราบว่าเวอร์ชันbashก่อนหน้า 4.3 มีการติดตาม symlink เมื่อเรียกแผนผังไดเรกทอรีซ้ำ (เช่นzsh's หรือtcsh' s ***/*) ซ้ำ

นอกจากนี้โซลูชันทั้งหมดข้างต้นจะไม่สนใจไฟล์ที่ซ่อนอยู่ (ผู้ที่มีชื่อขึ้นต้นด้วย a .ใช้shopt -s dotglobเพื่อรวมไฟล์เหล่านั้น) และจะรวมจำนวนบรรทัดของลิงก์สัญลักษณ์ (ซึ่งfindวิธีการจะไม่)


โปรดทราบว่าความแตกต่างอื่น ๆ จากการแก้ปัญหาของ jherran คือคุณจะพิจารณา symlink ไปยังไฟล์ปกติ ( -xtype fใน GNU find หรือ*(-.)in zsh) และจะละเว้นไฟล์ที่ซ่อนอยู่
Stéphane Chazelas

@ StéphaneChazelasขอบคุณชี้แจง ทำไมถึง%luอยู่ในprintf? ตามที่ฉันจำได้นั่นหมายถึงทศนิยมที่ไม่ได้ลงนามยาวมันจำเป็นจริงๆหรือ? ทำไมไม่ถือว่าตัวเลขเป็นสตริง? มันสร้างความแตกต่างหรือไม่?
terdon

2
หากเอาต์พุต wc ว่างเปล่า (เช่นเนื่องจากไฟล์ไม่สามารถอ่านได้) นั่นจะขยายเป็น0แทนที่จะเป็นสตริงว่างซึ่งดีกว่าเล็กน้อย การประยุกต์ใช้การเรียงลำดับบางอย่างทำงานกับจำนวนเต็มที่ไม่ได้ลงนามบางอย่างที่ลงนาม %luฟังดูเหมือนการเดิมพันที่ปลอดภัยที่สุด แต่ก็ไม่สำคัญว่าคุณจะมี2^31ไลน์หรือไม่
Stéphane Chazelas

1

หากคุณต้องการติดตั้งfdโปรแกรมค้นหาไฟล์ที่รวดเร็วจริงๆที่เขียนใน Rust (คุณควรติดตั้งมันก็ดีมากที่มีอยู่แล้ว)

fd --type=file . | xargs wc -l | sort -n

โดยทั่วไปfdจะแสดงรายการไฟล์ xargs จะผ่านรายการของไฟล์ไปwc(ย่อมาจากการนับจำนวนคำ แต่ผ่าน -l จะทำให้มันนับจำนวนบรรทัด) sort -nแล้วในที่สุดก็เรียงลำดับจากจำนวนที่น้อยที่สุดของสายที่จะยิ่งใหญ่ที่สุดโดยใช้

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