ไม่รวมไฟล์และไดเรกทอรีบางตัวเมื่อทำการลบไฟล์


11

dataไดเรกทอรีระดับบนสุดของฉันคือ dataมีหลายไดเรกทอรีและไดเรกทอรีเหล่านี้มีไดเรกทอรีย่อย ฉันต้องลบไฟล์และไดเรกทอรีdata/ทั้งหมดยกเว้นไฟล์หลายไฟล์ในบางไดเรกทอรี

ตัวอย่างเช่นข้อมูลรวมถึงไดเรกทอรีและ100 101ผมแค่อยากจะให้a.txtและb.txtไฟล์ใน100/และc.txtและd.txtไฟล์ใน101/ขณะที่ลบไฟล์อื่น ๆ ทั้งหมดและไดเรกทอรีในและ100101

ตัวอย่าง:

.
├── 100
   ├── a.txt
   ├── b.txt
   ├── c.txt
   └── d.txt
└── 101
    ├── a.txt
    ├── b.txt
    ├── c.txt
    └── d.txt

ฉันใช้rm -rf !(a.txt|b.txt)คำสั่ง แต่ฉันไม่สามารถใช้คำสั่งนี้สำหรับแต่ละไดเรกทอรีโดยอัตโนมัติ

คำตอบ:


12

เมื่อคุณค้นพบแล้วคุณสามารถใช้extglobคุณสมบัติที่เปิดใช้งานด้วย:

shopt -s extglob

สิ่งนี้อนุญาตให้แยกการจับคู่เพื่อให้คุณสามารถทำสิ่งต่าง ๆ เช่น:

rm 100/!([ab].txt) 101/!([cd].txt)

เป็นความคิดที่ดีที่จะทดสอบด้วยechoก่อน ตัวอย่างนี้จะตรงกับสิ่งที่อยู่ภายใน100/ซึ่งไม่ได้a.txtหรือb.txtและภายในอะไร101/ซึ่งไม่ได้หรือc.txt d.txtหากใช้กฎเดียวกัน100/กับ102/เช่นกันคุณสามารถทำได้เช่น:

10[02]/!([ab].txt) # or
{100,102}/!([ab].txt)

ฉันเพิ่งให้ตัวอย่างสำหรับ 100 และ 101 ไดเรกทอรี แต่ในความเป็นจริงจำนวนไดเรกทอรีย่อยเกือบ 20 มีวิธีการใช้รหัสข้างต้นสำหรับแต่ละไดเรกทอรีโดยไม่ต้องเขียนชื่อแต่ละไดเรกทอรีในโฟลเดอร์หลักหรือไม่
deepblue

@deepblue โปรดระบุตัวอย่างที่แน่นอนสำหรับคำถามของคุณ ( แก้ไข ) โดยเฉพาะอย่างยิ่งที่ไม่ชัดเจนว่าrmควรทราบว่าไฟล์ใดควรเก็บไว้ในไดเรกทอรีใดถ้าคุณไม่ต้องการระบุ
ของหวาน

7

คุณสามารถใช้findสิ่งนี้ คุณสามารถปฏิเสธการทดสอบในfindด้วยหรือ-not !วิธีนี้จะยกเว้นการแข่งขันแทนที่จะค้นหา

คุณควรระวังไม่ให้ลบพาเรนต์ไดเร็กทอรีใด ๆ ของไฟล์ที่คุณต้องการเก็บไว้โดยเฉพาะไดเร็กทอรีปัจจุบัน .ดังนั้นให้แน่ใจว่าคุณอ่านเอาต์พุตอย่างละเอียดก่อนที่จะลบ

จากตัวอย่างของคุณคุณสามารถทำสิ่งนี้จากdataไดเรกทอรี

find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt"

เพิ่ม! -path ./path/to/dirเส้นทางใด ๆ ที่คุณต้องการหลีกเลี่ยงการลบ คุณสามารถใช้ metacharacters เช่น*แต่ให้แน่ใจว่าคุณพูดถึงการแสดงออกถ้าคุณทำเช่น"./path*dir"เพื่อป้องกันการขยายตัวที่ไม่พึงประสงค์

findจะเรียกซ้ำโดยค่าเริ่มต้น แม้ว่าเราจะไม่พบที่นี่เราจะได้พบกับเนื้อหาทั้งหมดจนกว่าพวกเขาจะตรงกับรูปแบบ./100 [ab].txtหากคุณไม่สามารถจับคู่ชื่อทั้งหมดที่คุณต้องการเก็บไว้เพิ่มการทดสอบอื่น:

! -path "./100/[ab].txt" ! -path ./100/foo

สิ่งนี้จะไม่พบa.txtหรือb.txtหรือfooแต่จะหาไฟล์อื่นทั้งหมด

เมื่อคุณแน่ใจว่าคุณเห็นสิ่งที่คุณต้องการคุณสามารถเพิ่ม-deleteท้ายเพื่อลบไฟล์ที่พบ:

find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt" -delete
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.