ฉันจะลบไดเรกทอรีว่างทั้งหมดในทรีย่อยได้อย่างไร ฉันใช้สิ่งที่ชอบ
find . -type d -exec rmdir {} 2>/dev/null \;
แต่ฉันต้องทำงานหลายครั้งเพื่อลบไดเรกทอรีที่มีไดเรกทอรีว่างเท่านั้น ยิ่งกว่านั้นมันค่อนข้างช้าโดยเฉพาะอย่างยิ่งใน cygwin
ฉันจะลบไดเรกทอรีว่างทั้งหมดในทรีย่อยได้อย่างไร ฉันใช้สิ่งที่ชอบ
find . -type d -exec rmdir {} 2>/dev/null \;
แต่ฉันต้องทำงานหลายครั้งเพื่อลบไดเรกทอรีที่มีไดเรกทอรีว่างเท่านั้น ยิ่งกว่านั้นมันค่อนข้างช้าโดยเฉพาะอย่างยิ่งใน cygwin
คำตอบ:
การรวมfind
ตัวเลือกGNU และเพรดิเคตคำสั่งนี้ควรทำงาน:
find . -type d -empty -delete
-type d
จำกัด เฉพาะไดเรกทอรี-empty
จำกัด เฉพาะสิ่งที่ว่างเปล่า-delete
ลบแต่ละไดเรกทอรีต้นไม้นั้นเดินจากใบไม้โดยไม่จำเป็นต้องระบุ-depth
ตามที่บอก-delete
ไว้
-delete
แสดงนัยแล้ว-depth
ดังนั้นคุณไม่จำเป็นต้องระบุด้วยตนเอง
-mindepth 1
ที่นี่เพื่อป้องกันการลบไดเรกทอรีเริ่มต้นตัวเองถ้ามันจะว่างเปล่า
!
มีความหมายพิเศษสำหรับเชลล์ คุณต้องหลบหนี สิ่งที่ต้องการ: \! -name 'Completed'
ก่อนหน้านี้-delete
ควรทำงาน หรือคุณเพียงแค่ใส่ไฟล์เครื่องหมายในไดเรกทอรีนี้
รายการไดเรกทอรีที่ซ้อนกันลึกก่อน
find . -depth -type d -exec rmdir {} \; 2>/dev/null
(โปรดทราบว่าการเปลี่ยนเส้นทางใช้กับfind
คำสั่งโดยรวมไม่ใช่เพื่อการrmdir
เปลี่ยนเส้นทางเพียงอย่างเดียวrmdir
จะทำให้การทำงานช้าลงอย่างมากเนื่องจากคุณต้องเรียกใช้เชลล์ระดับกลาง)
คุณสามารถหลีกเลี่ยงการรันrmdir
บนไดเร็กทอรีที่ไม่ว่างโดยส่งเพรดิเคต-empty
เพื่อค้นหา GNU ค้นหาการทดสอบไดเรกทอรีเมื่อมันกำลังจะเรียกใช้คำสั่งดังนั้นไดเรกทอรีที่เพิ่งถูกลบจะถูกหยิบขึ้นมา
find . -depth -type d -empty -exec rmdir {} \;
อีกวิธีในการเร่งความเร็วก็คือจัดกลุ่มrmdir
คำร้อง ทั้งสองมีแนวโน้มว่าจะเร็วกว่าเดิมอย่างเห็นได้ชัดโดยเฉพาะอย่างยิ่งภายใต้ Cygwin ฉันไม่คาดหวังความแตกต่างระหว่างสองสิ่งนี้มากนัก
find . -depth -type d -print0 | xargs -0 rmdir 2>/dev/null
find . -depth -type d -exec rmdir {} + 2>/dev/null
วิธีที่เร็วกว่านั้นขึ้นอยู่กับว่าคุณมีไดเรกทอรีที่ไม่ว่างจำนวนเท่าใด คุณไม่สามารถรวม-empty
กับวิธีสำหรับการจัดกลุ่มการเรียกใช้เนื่องจากไดเรกทอรีที่มีไดเรกทอรีที่ว่างเปล่าเท่านั้นจะไม่ว่างเปล่าตามเวลาที่find
ดู
อีกวิธีหนึ่งก็คือการวิ่งผ่านหลายรอบ สิ่งนี้เร็วกว่าหรือไม่ขึ้นอยู่กับหลาย ๆ อย่างรวมถึงลำดับชั้นของไดเรกทอรีทั้งหมดที่สามารถอยู่ในดิสก์แคชระหว่างการfind
รันได้หรือไม่
while [ -n "$(find . -depth -type d -empty -print -exec rmdir {} +)" ]; do :; done
หรือใช้ zsh ตัวระบุคุณสมบัติกลม F
จับคู่กับไดเรกทอรีที่ไม่ว่างดังนั้นจึง/^F
จับคู่ไดเรกทอรีว่าง ไดเรกทอรีที่มีเฉพาะไดเรกทอรีที่ว่างเปล่าไม่สามารถจับคู่ได้อย่างง่ายดาย
while rmdir **/*(/N^F); do :; done
(สิ่งนี้จะสิ้นสุดเมื่อrmdir
ได้รับบรรทัดคำสั่งว่าง)
-p
หรือไม่? ฉันไม่คิดว่ามันจะสร้างความแตกต่าง
-empty
ควรทำงานกับอันนี้ได้ (แม้ว่าฉันไม่แน่ใจว่าจะได้รับเท่าใด) และมากนิด ๆ เพราะคุณอาจไม่ต้องการที่จะลบการใช้งาน.
-mindepth 1
-depth
ข้อโต้แย้งซึ่งทำให้rmdir -p
ไร้ประโยชน์ ฉันเปลี่ยนความคิดเห็นแล้ว 90 s เป็นความพยายามดั้งเดิมของฉัน ไม่มีอะไรน่าแปลกใจที่นี่
rmdir
เรียกคำสั่งทั้งหมดอย่างน้อยด้วย GNU find ด้วยคำสั่งนี้:find . -depth -type d -empty -delete
หากคุณเพียงแค่ตะปู-p
บนของคุณrmdir
ที่จะทำงานในรอบเดียว มันจะไม่สวยหรือดีที่สุด แต่ควรได้ทุกอย่าง ซึ่งบอกให้ rmdir ลบไดเรกทอรีพาเรนต์ที่ไม่ว่างของไดเรกทอรีที่คุณกำลังลบ
คุณสามารถบันทึกได้เล็กน้อยโดยเพิ่มการ-empty
ทดสอบเพื่อค้นหาดังนั้นจึงไม่ต้องกังวลกับไดเรกทอรีที่ไม่ว่างเปล่า
find . -depth -type d -exec rmdir {} +
เป็นคำตอบที่ง่ายและได้มาตรฐานสำหรับคำถามนี้
คำตอบอื่น ๆ ที่ให้ไว้ที่นี่น่าเสียดายทั้งหมดขึ้นอยู่กับการปรับปรุงเฉพาะของผู้ขายที่ไม่มีอยู่ในทุกระบบ
find . -type d -printf "%d %p\n" |\
sort -nr |\
perl -pe 's/^\d+\s//;' |\
while read dir; do \
(rmdir "$dir" > /dev/null 2>&1); \
done
นี่คือวิธีการทำงาน:
rmdir
ในรายการหนึ่งโดยหนึ่งฉันใช้นามแฝงเหล่านี้สำหรับfind
คำสั่งที่ใช้บ่อยโดยเฉพาะอย่างยิ่งเมื่อฉันล้างพื้นที่ดิสก์โดยใช้dupeguruซึ่งการลบรายการที่ซ้ำกันอาจส่งผลให้เกิดไดเรกทอรีว่างจำนวนมาก
ความเห็นด้านใน.bashrc
ดังนั้นฉันจะไม่ลืมพวกเขาในภายหลังเมื่อฉันต้องการปรับแต่ง
# find empty directories
alias find-empty='find . -type d -empty'
# fine empty/zero sized files
alias find-zero='find . -type f -empty'
# delete all empty directories!
alias find-empty-delete='find-empty -delete'
# delete empty directories when `-delete` option is not available.
# output null character (instead of newline) as separator. used together
# with `xargs -0`, will handle filenames with spaces and special chars.
alias find-empty-delete2='find-empty -print0 | xargs -0 rmdir -p'
# alternative version using `-exec` with `+`, similar to xargs.
# {}: path of current file
# +: {} is replaced with as many pathnames as possible for each invocation.
alias find-empty-delete3='find-empty -exec rmdir -p {} +'
# for removing zero sized files, we can't de-dupe them automatically
# since they are technically all the same, so they are typically left
# beind. this removes them if needed.
alias find-zero-delete='find-zero -delete'
alias find-zero-delete2='find-zero -print0 | xargs -0 rm'
alias find-zero-delete3='find-zero -exec rm {} +'
rm -r */
คำสั่งทำงานได้อย่างง่ายดายสำหรับฉัน rm
ควรบังคับ-f
ให้ลบไดเรกทอรีพร้อมไฟล์ rm -r
ควรลบไดเรกทอรีที่ว่างเปล่าเท่านั้น ฉันเปิดให้ทำไมสิ่งนี้อาจผิด สิ่งนี้ควรปล่อยให้ไฟล์ไว้เพราะ*/
ดูเฉพาะโฟลเดอร์
rm
มีวัตถุประสงค์หลักเพื่อลบไฟล์ ในขณะที่*/
ตรงกับไดเรกทอรีเท่านั้นฉันไม่ทราบว่ามันทำอะไรในระดับลึก ฉันสามารถจินตนาการได้ว่ามันใช้ได้กับบางระบบเท่านั้น