ลบไดเรกทอรีย่อยทั้งหมดยกเว้นหนึ่งรายการ


10

สมมติว่าภายใต้ไดเรกทอรีปัจจุบันมีหลายไดเรกทอรีย่อยและหนึ่งเรียกว่า A.

วิธีการลบไดเรกทอรีย่อยทั้งหมดยกเว้น A กับ Bash

คำตอบ:


23

ทุบตีขยาย globbing (ทดสอบครั้งแรกแล้วเอาเสียงก้อง):

shopt -s extglob
echo rm -rf !(A)

(ก่อนที่ฉันจะลืม - คุณอาจปิดการใช้งานประวัติสไตล์ CSH ใน Bash3 มีข้อผิดพลาดในขณะที่ไม่สนใจ! (. set + H

+1 Bash ถ้าเต็มไปด้วยความประหลาดใจ! บางครั้งพวกเขาก็ดีเช่นนี้
Aleksandr Levchuk

ดีมากแน่นอน! ทำงานได้ตามที่คาดหวัง ด้วยshopt | grep extคุณสามารถดูว่ามีการเปิดใช้งานปลั๊กอินหรือไม่
danger89


10

เกี่ยวกับ:

mv A /tmp/
rm * -rf
mv /tmp/A .

วิธีนี้จะช่วยหลีกเลี่ยง "ความเหลว" ของคำที่พิมพ์ผิดในคำสั่งอื่น


1
+1 สำหรับทำสิ่งที่มีสติแทนที่จะหวังว่าเครื่องมือนั้นฉลาดพอ ยังคืนหนึ่งเมื่อฉันเพิ่งเรียนรู้ Linux ฉันคัดลอกเคอร์เนลไปที่ / tmp ก่อนที่จะทำการคอมไพล์ครั้งแรกของฉัน มันไม่ประสบความสำเร็จ แต่ลบไฟล์เก่าออกดังนั้นฉันจึงพูดว่า 'ไม่มีเหงื่อฉันมีสำเนา' เพียงเพื่อพบว่างาน cron เที่ยงคืนได้ลบมันด้วยไฟล์ทุกไฟล์ที่มีอายุมากกว่าหนึ่งสัปดาห์ใน / tmp! ฉันต้องคอมไพล์อีกครั้งและในครั้งนี้ทำถูกต้องหรือไม่รีบูตเครื่องสำหรับฉัน!
Javier

คำตอบที่ดีที่สุด :) โพสต์
วอร์เรน

3

สิ่งที่ต้องการ

find . -type d -not -name A -exec rm -ir {} \;

ควรทำ.

แก้ไข

มันควรจะเป็นจริง

find . -type d -maxdepth 1 -not -name A -exec rm -ir {} \;

เพื่อป้องกันการfindเรียกซ้ำด้านล่าง A.


3
แต่สิ่งนี้จะลบไดเรกทอรีย่อยใด ๆ ด้านล่าง A เช่น A / foo และ A / bar แต่จะเก็บ A / A ไว้
TCampbell

เย็น! คำถามและ answert รับโอนย้ายจากเอสเอฟเพื่อที่จะแก้ไข ... แต่ฉันข้างต้นก็หายไป ...
agnul

มันควรจะดีกว่าที่จะสลับ maxdepth และอาร์กิวเมนต์ประเภทเช่นนี้: find -maxdepth 1 -type d -not -name A -exec rm -ir {} \;
Spawnrider

1

ฉันมักจะทำโดยการทำงานคำสั่ง ls ที่ทำให้ถูกต้องก่อน ฉันไม่ได้อยู่ที่เครื่องยูนิกซ์ แต่มีสิ่งที่ชอบ:

ls -lda "[^ A]"

เมื่อคุณทำให้ถูกต้องท่อไปยังคำสั่ง

ls -lda "[^ A]" | xargs rm -rf

อย่าลังเลที่จะแก้ไขข้างต้นถ้าฉันทำผิดปกติ ...



1

หากคุณต้องการความยืดหยุ่นมากขึ้น แต่ด้วยตนเองคุณสามารถทำได้:

ls > /tmp/foo
edit /tmp/foo as you like
xargs -a /tmp/foo rm -r

ด้วยวิธีนี้คุณสามารถทำการร้องทั่วไปได้


1

นี่คือวิธีหนึ่ง ระวังสิ่งเหล่านี้ด้วยมันมีพลังมากที่มันจะใช้ได้ดีหรือชั่ว ...

ค้นหา * -type d | grep -v "^ A" | xargs rm -rf

1

อย่าใช้การค้นหาเนื่องจากบางคนแสดงด้วย -exec และ rm โดยไม่ผ่าน -print0 เพื่อค้นหาและ -0 ถึง xargs มันจะสับสนในชื่อไฟล์ที่มีช่องว่างหรือขึ้นบรรทัดใหม่:

$ mkdir 'foo foo'
$ mkdir foo$'\n'foo 
$ find . -type d -exec rm -ir {} \;
rm: cannot remove directory `.'
rm: remove directory `./foo\nfoo'? y
find: `./foo\nfoo': No such file or directory
rm: remove directory `./foo foo'? y
find: `./foo foo': No such file or directory

ให้ใช้ find -print0 ที่มี xargs -0, '-exec command {} +' หรือ -delete หากการค้นหาของคุณรองรับ



1

นอกเหนือจากตัวอย่างก่อนหน้าของ:

find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;

คุณสามารถทำได้:

find some/subdir -mindepth 1 -maxdepth 1 -type d -not -name A -exec rm -ir {} \;

เพื่อหลีกเลี่ยงการต้องcd some/subdirก่อน

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