ไม่รวมโฟลเดอร์ย่อยที่มีไฟล์เฉพาะใน recursive rm -rf / folder / *


4

ฉันสงสัยว่าเป็นไปได้หรือไม่ที่จะระบุเงื่อนไขที่หรูหรา (พารามิเตอร์อาจ?) ใน rm -rf /folder/* ไม่ต้องลบโฟลเดอร์ย่อยซึ่งมีไฟล์ชื่อ "dontshoot.txt"

ฉันหาอะไรไม่ได้เลย

ขอบคุณล่วงหน้าสำหรับความช่วยเหลือของ!


1
เพื่อความรู้ของฉัน rm ไม่สามารถยกเว้นรูปแบบได้คุณจะต้องเขียนฟังก์ชันหรือสคริปต์เพื่อทำสิ่งนี้
Cobra_Fast

คำตอบ:


7

คุณสามารถใช้ find อย่างนี้

find some_folder ! -name dontshoot.txt -delete

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

find some_folder ! -name dontshoot.txt 

อย่างไรก็ตามสิ่งนี้จะแสดงรายการโฟลเดอร์ทั้งหมดแม้แต่ที่มีอยู่ dontshoot.txt แต่จะไม่ถูกลบเนื่องจากจะไม่ว่างเปล่าเมื่อใช้งาน -delete.

แก้ไข:

ฉันยอมรับว่าการตีความ fedorqui ของคำถามนั้นสมเหตุสมผลกว่าของฉัน เพื่อลบเฉพาะโฟลเดอร์ที่ไม่มี dontshoot.txt ส่วนลึกลงไปในโครงสร้างต้นไม้ของพวกมัน

find some_folder -type d -exec \
   sh -c "find {} -name dontshoot.txt | grep -q '' || echo rm -fr {}" \;

คำอธิบาย:

ด้านนอก find ลัดวงจรคำสั่งผ่านซ้ำ ๆ some_folder ค้นหาไดเรกทอรีทั้งหมด ( -type d ) และดำเนินการ ( -exec ) คำสั่งเชลล์ที่กำหนดในขณะที่แทนที่ {} โดยพา ธ สัมพัทธ์ไปยังไดเรกทอรีที่พบ

find คำสั่งภายในเปลือกค้นหาไดเรกทอรีที่พบ dontshoot.txt. หากไม่พบสิ่งใดจะไม่มีการส่งออกไปยัง grep -q '' ซึ่งจะกลับมา False และส่วนสุดท้ายจะถูกดำเนินการซึ่งจะลบไดเรกทอรีเต็มรูปแบบ (ซึ่งไม่ได้มีแน่นอน dontshoot.txt ) ซ้ำ ๆ

ในระยะสั้นมันสำรวจไดเรกทอรีทั้งหมดและลบผู้ที่ไม่มี dontshoot.txt บางแห่งในนั้น


ฉันมีข้อสงสัยหนึ่งอย่าง: ถ้าเรามีโฟลเดอร์ t / ด้วย dontshoot.txt และ otherfile.txt? ฉันคิดว่ารหัสของคุณจะลบ otherfile.txtแม้ว่าฉันเดาว่ามันไม่ควรอิงจาก OP
fedorqui

ใช่คุณพูดถูกฉันได้ขยายคำตอบไปสู่การตีความคำถามที่สมเหตุสมผลมากขึ้น
buergi

ยินดีด้วยนี่เป็นคำตอบที่ยอดเยี่ยมมาก!
fedorqui

3

ไม่สามารถยกเว้นได้ภายใน rm คำสั่ง

คุณสามารถทำสิ่งนี้:

for dir in /folder/*
do
  echo $dir
  if [ ! -f "$dir/dontshoot.txt" ]; then
    rm -rf "$dir"
   fi
done

สำคัญ:

ตรวจสอบด้วย ls แทน rm ก่อนดำเนินการ


ฉันได้รับการโหวตขึ้นและลงในเวลาเดียวกัน!
fedorqui

1
ไม่ใช่ฉันฉันสาบาน! ขอบคุณที่ตอบกลับฉันจะตรวจสอบ
mr.nothing

1
@ mr.nothing ลองใช้คำสั่งของคุณด้วย ls ก่อนที่จะใช้กับ rm!
fedorqui

@fedorqui อาจเป็นทางออกที่ดีที่สุด ฉันพยายามทำบางสิ่งด้วย findแต่ฉันไม่คิดว่าเงื่อนไขนี้จะสามารถชดเชยได้
glglgl

1
ปัญหาเกี่ยวกับวิธีแก้ปัญหานี้คือมันไม่ทำงานซ้ำ ๆ อย่างไรก็ตามคำถามไม่ได้ทำให้ชัดเจนถ้าเป็นที่ต้องการหรือไม่
buergi

1

ฟังก์ชั่นต่อไปนี้สามารถใช้งานได้ฉันไม่มีเวลาทดสอบ

// $1 = directory to remove
// $2 = exclude pattern
function rmx()
{
    rm -f $(find $1 * | grep -v $2)
}

โทรเหมือน

rmx get/rid/of/this/ ".*?not-these-files.*?"

บางทีนี่อาจเป็นแนวคิดอย่างหนึ่งในการจัดการกับปัญหานี้ ...


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