ค้นหาไดเรกทอรีที่มีไฟล์จำนวนหนึ่ง


13

หวังว่าฉันจะสามารถทำสิ่งนี้ได้ด้วยfindคำสั่ง แต่ฉันไม่เห็นการทดสอบในคู่มือสำหรับการทำสิ่งที่ฉันต้องการ ฉันต้องการหาไดเรกทอรีใด ๆ ในไดเรกทอรีทำงานที่มีจำนวนน้อยกว่าหรือมากกว่าจำนวนที่ฉันระบุ

find . -filecount +10 # any directory with more than 10 entries
find . -filecount 20 # any directory with exactly 20 entries

แต่อนิจจาไม่มีตัวเลือกดังกล่าว


ลองอะไรเช่น "ls -al | wc -l | grep"
Vanadis

คำตอบ:


16

คุณสามารถลองนี้เพื่อรับชื่อไดเรกทอรีย่อยและจำนวนไฟล์ / ไดเรกทอรีที่มี:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \;

หากคุณต้องการทำเช่นเดียวกันสำหรับไดเรกทอรีย่อยทั้งหมด (ค้นหาแบบเรียกซ้ำ) ให้ใช้สิ่งนี้แทน:

find . -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \;

ในการเลือกไดเรกทอรีเหล่านั้นที่มีไฟล์ 10 ไฟล์:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
  awk '$NF==10'

10 หรือมากกว่า:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
 awk '$NF>=10'

10 หรือน้อยกว่า:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
 awk '$NF<=10'

หากคุณต้องการเก็บเฉพาะชื่อไดเรกทอรี (ตัวอย่างเช่นคุณต้องการไพพ์ไปยังกระบวนการดาวน์สตรีมตามที่ @evilsoup แนะนำ) คุณสามารถใช้สิ่งนี้:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{}\t'; ls '{}' | wc -l" \; | 
 awk -F"\t" '$NF<=10{print $1}'

1
ฉันคิดว่ามันอาจจะมีประโยชน์ที่จะรวมคำสั่ง awk เพื่อตัดจำนวนไฟล์ (เช่นคอลัมน์ที่คั่นด้วยช่องว่างสุดท้าย) ในกรณีที่ผู้ถามต้องการไพพ์เอาท์พุทเป็นอย่างอื่น
evilsoup

1
@evilsoup ความคิดที่ดีเสร็จแล้ว
terdon

เพื่อรองรับช่องว่างสีขาวและอักขระพิเศษในชื่อไดเรกทอรี ลองย้อนกลับของการใช้คำพูดเดียวและสองเป็นเช่นนี้:find . -type d -exec bash -c 'echo -ne "{} "; ls "{}" | wc -l' \; | awk '$NF<=10'
Håvard Geithus

3

เพื่อแสดงรายการไดเรกทอรีย่อยทันทีที่มีว่า $NUMไฟล์

find -maxdepth 2 -mindepth 2 -type f -printf '%h\0' | awk -v num="$NUM" 'BEGIN{RS="\0"} {array[$0]++} END{for (line in array) if (array[line]==num) printf "%s\n", line}'

เพื่อแสดงรายการไดเรกทอรีย่อยทันทีที่มีมากขึ้นกว่า$NUMไฟล์

find -maxdepth 2 -mindepth 2 -type f -printf '%h\0' | awk -v num="$NUM" 'BEGIN{RS="\0"} {array[$0]++} END{for (line in array) if (array[line]>num) printf "%s\n", line}'

ในการแสดงรายการไดเรกทอรีย่อยทันทีที่มีไฟล์น้อยกว่า$NUM

find -maxdepth 2 -mindepth 2 -type f -printf '%h\0' | awk -v num="$NUM" 'BEGIN{RS="\0"} {array[$0]++} END{for (line in array) if (array[line]<num) printf "%s\n", line}'

รายการจะถูกยกเลิกด้วยอักขระ null \0ดังนั้นชื่อไฟล์ที่มีบรรทัดใหม่หรือพื้นที่สีขาวประเภทอื่น ๆ จะถูกตีความอย่างถูกต้อง พิมพ์แต่ละไฟล์เป็น%h จากนั้นใช้อาร์เรย์เพื่อนับจำนวนครั้งที่พบแต่ละไดเรกทอรีพิมพ์ถ้าตรงตามเงื่อนไขdirnameawk

โปรดทราบว่าคำสั่งข้างต้นจะไม่แสดงไดเรกทอรีที่มีไฟล์ศูนย์ โปรดทราบว่าด้วยไฟล์ฉันหมายถึงไฟล์ปกติไม่ใช่ลิงก์ไดเรกทอรีซ็อกเก็ตบล็อกชื่อไปป์และอื่น ๆ

ฉันพยายามทำสิ่งนี้ให้ง่ายที่สุด หากคุณต้องการค้นหาไดเรกทอรีย่อยซ้ำหรือไฟล์ในนั้นจำเป็นต้องมีคำสั่งแก้ไข มีความเป็นไปได้มากเกินไปที่จะแสดงรายการทั้งหมด


2

ลองสิ่งนี้:

[ค้นหา | ห้องสุขา -l` -eq 10] && echo "พบ"

[ค้นหา | wc -l` -gt 10] && echo "พบ"

[ค้นหา | wc -l` -lt 10] && echo "พบ"

ในตัวอย่างนี้คุณสามารถตรวจสอบว่าไดเรกทอรีปัจจุบันประกอบด้วย 10, มากกว่า 10 และน้อยกว่า 10 ไฟล์ / ไดเรกทอรี หากคุณต้องการตรวจสอบไดเรกทอรีต่างๆให้ใช้การวนซ้ำ


โซลูชันของคุณยังนับไดเรกทอรีปัจจุบัน ( .) คุณอาจต้องการแก้ไขตาม
terdon

ฉันชอบแรงขับของคำตอบนี้ (เพราะฉันเป็นคนตะกละสำหรับทำสิ่งต่างๆในเปลือกหอย) แต่คุณควรใช้wc -l < <(printf %s\\n ./*)หรือใช้printf %s\\n ./* | wc -lในการทดสอบดีกว่าเพื่อหลีกเลี่ยงการfindโทรที่ไม่จำเป็น สิ่งนี้จะหลีกเลี่ยงปัญหาที่ @terdon ระบุไว้ซึ่งรวมถึง.ผลลัพธ์ด้วย อย่างไรก็ตามมันก็จะพบปัญหาในการละเลยไฟล์ที่เริ่มต้นด้วย.; ฉันจะแก้ปัญหานี้ด้วยshopt -s dotglob(เพื่อให้ไฟล์จับคู่ globs เริ่มต้นด้วย.แต่ไม่ใช่.หรือ..)
evilsoup

@terdon มันไม่สำคัญ มันไม่ใช่ทางออกสุดท้ายเพียงแค่ตัวอย่างความคิด คุณสามารถ -1 หรือเปลี่ยน 10 เป็น 11 ในรุ่นสุดท้าย
กันยายน

ฉันรู้และความคิดนั้นดีนั่นคือสาเหตุที่ฉันทำข้อเสนอแนะ
terdon

@ terdon ขอบคุณ. อาจมีข้อกำหนดที่แตกต่างกันมากมายเช่น: นับเฉพาะไฟล์ แต่ไม่ใช่ไดเรกทอรีหรือลิงก์หรือฮาร์ดลิงก์ นับหรือไม่ไฟล์ในไดเรกทอรีย่อย นับจำนวนไฟล์ที่ซ่อนอยู่ (เช่น. bashrc) ... ... เพื่อให้การแสดงออกของคุณเป็นไปได้ด้วยดี :)
กันยายน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.