find -delete ไม่ได้ลบไดเรกทอรีที่ไม่ว่างเปล่า


32

คำสั่ง

$ find ~ -name .DS_Store -ls -delete

ใช้งานได้กับ Mac OS X แต่

$ find ~ -name __pycache__ -type d -ls -delete

ไม่พบ - พบไดเร็กทอรี แต่ไม่ถูกลบ

ทำไม?

PS ฉันรู้ว่าฉันสามารถทำ

$ find ~ -name __pycache__ -type d -ls -exec rm -rv {} +

คำถามคือว่าทำไม find -deleteไม่ได้ทำงาน

คำตอบ:


36

findการ-deleteตั้งค่าสถานะทำงานคล้ายกับrmdirเมื่อลบไดเรกทอรี หากไดเรกทอรีไม่ว่างเปล่าเมื่อถึงไดเรกทอรีจะไม่สามารถลบได้

คุณต้องทำให้ไดเรกทอรีว่างก่อน เนื่องจากคุณกำลังระบุ-type d, findจะไม่ทำเพื่อคุณ

คุณสามารถแก้ปัญหานี้ได้โดยทำสองรอบ: ก่อนอื่นให้ลบทุกอย่างภายใน dirs ที่มีชื่อ__pycache__จากนั้นลบ dirs ทั้งหมดที่มีชื่อ__pycache__:

find ~ -path '*/__pycache__/*' -delete
find ~ -type d -name '__pycache__' -empty -delete

ควบคุมได้ค่อนข้างน้อย แต่ในบรรทัดเดียว:

find ~ -path '*/__pycache__*' -delete

การดำเนินการนี้จะลบสิ่งใด ๆ ในบ้านของคุณที่__pycache__เป็นส่วนหนึ่งของเส้นทาง


ในการค้นหา 4.4.2 คำสั่งสุดท้ายนั้นจำเป็นต้องมีfind ~ -path '*/__pycache__*' -deleteหรืออาจfind ~ -path '*/__pycache__/*' -o -name __pycache__ -deleteจะปลอดภัย
naught101

3
@ naught101 ที่ควรจะfind ~ \( -path '*/__pycache__/*' -o -name __pycache__ \) -deleteเป็นและมีความสำคัญเหนือกว่าหรือ
Stéphane Chazelas

6

มีสาเหตุที่เป็นไปได้สองสามประการสำหรับเรื่องนี้

1) คุณบอกให้ลบไดเรกทอรีเท่านั้น ( -type d) และไดเรกทอรีเหล่านั้นยังคงมีไฟล์อยู่ข้างใน

2) ไดเรกทอรีของคุณมีเพียงไดเรกทอรีอื่น ๆ ดังนั้น-type dจะดูแลปัญหาเนื้อหา อย่างไรก็ตามคุณใช้ OS-X ซึ่งส่วนใหญ่ใช้ FreeBSD และ FreeBSD เป็นfindค่าเริ่มต้นจะประมวลผลไดเรกทอรีก่อนเนื้อหา
อย่างไรก็ตามมี-depthตัวเลือกในการแก้ปัญหานี้โดยบอกfindให้ประมวลผลไดเรกทอรีหลังจากเนื้อหา

find ~ -name __pycache__ -type d -ls -delete -depth

ปัญหานี้ไม่ได้อยู่ในลินุกซ์เพราะตัวเลือกที่ช่วยให้โดยปริยาย-delete-depth

 

FreeBSD man 1 find:

 -depth  Always true; same as the non-portable -d option. Cause find to
   perform a depth-first traversal, i.e., directories are visited in
   post-order and all entries in a directory will be acted on before
   the directory itself. By default, find visits directories in
   pre-order, i.e., before their contents. Note, the default is not
   a breadth-first traversal.

GNU man 1 find:

 -depth Process each directory's contents before the directory itself. The -delete
        action also implies -depth.

2
ใช่ แต่การค้นหา FreeBSDบอกว่า-delete“ …การประมวลผลการสำรวจเส้นทางลึกครั้งแรกนั้นถูกบอกเป็นนัยโดยตัวเลือกนี้” และGNU พบ (1)พูดว่า“ … -deleteบอกเป็นนัย - ลึก , …” ดังนั้นจึงไม่ควร จำเป็นต้องเพิ่ม-depthคำสั่ง
G-Man กล่าวว่า 'Reinstate Monica'

1
จาก GNU findmanpage: "เพื่อป้องกันความสับสนตัวเลือกทั่วโลกควรระบุในบรรทัดคำสั่งหลังจากรายการของจุดเริ่มต้นก่อนการทดสอบครั้งแรกตัวเลือกตำแหน่งหรือการกระทำหากคุณระบุตัวเลือกทั่วโลกในที่อื่น ออกข้อความเตือนว่าอาจทำให้เกิดความสับสนได้ " ตอนนี้-deleteเป็น "ตัวเลือกทั่วโลก" หลังจากที่~ในคำสั่งที่กำหนด ฉันได้สังเกตเห็นด้วยว่ามันไม่ได้สร้างความแตกต่างไม่ว่าคุณจะเพิ่ม-depthหรือไม่ก็ตาม ไดเรกทอรีที่ว่างเปล่ายังไม่ถูกลบ (แต่อาจเป็นเพราะฉันใช้-maxdepthด้วย)
David Tonhofer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.