ฉันต้องการลบไดเรกทอรี B และ D แต่ฉันต้องการเก็บ C และไฟล์และไดเรกทอรีที่สืบทอดทั้งหมด อะไรคือคำสั่งที่จะลบไดเรกทอรีลูกทั้งหมดของไดเรกทอรีแม่ยกเว้นหนึ่งไดเรกทอรีและลูก ๆ ของมัน
ช่วยชื่นชม
Aในตัวอย่างของคุณ) ล่ะ? ลบพวกเขาเช่นกันหรือเก็บไว้?
ฉันต้องการลบไดเรกทอรี B และ D แต่ฉันต้องการเก็บ C และไฟล์และไดเรกทอรีที่สืบทอดทั้งหมด อะไรคือคำสั่งที่จะลบไดเรกทอรีลูกทั้งหมดของไดเรกทอรีแม่ยกเว้นหนึ่งไดเรกทอรีและลูก ๆ ของมัน
ช่วยชื่นชม
Aในตัวอย่างของคุณ) ล่ะ? ลบพวกเขาเช่นกันหรือเก็บไว้?
คำตอบ:
สิ่งที่คุณต้องการคือคำสั่งนี้:
find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;
# List what's inside directory we want to remove
$ ls
file1 file2 keepMe/ removeA/ removeB/
# Testing what find gives without removing
$ find ~/TESTDIR -mindepth 1 -type d -not \( -name "keepMe" \)
/home/xieerqi/TESTDIR/removeA
/home/xieerqi/TESTDIR/removeB
# Actual removal and testls
$ find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;
$ ls
file1 file2 keepMe/
find DIRECTORY เรียกใช้คำสั่ง find เพื่อทำงานกับ DIRECTORY-mindepth 1 : ทำงานเฉพาะกับเนื้อหาของไดเรกทอรีหลีกเลี่ยงไดเรกทอรีที่ระดับ 0-maxdepth 1: ป้องกันการลดระดับลงในไดเรกทอรีย่อย ( rm -rfเรียกซ้ำได้ดังนั้นเราจึงไม่จำเป็นต้องลงไปในไดเรกทอรีย่อยเพื่อลบออก)-type d : ค้นหาเฉพาะไดเรกทอรี-not \( -name "keepMe" \) เพิกเฉยรายการที่มีชื่อที่คุณต้องการเก็บ-exec rm -rf {} \; ดำเนินการลบรายการที่พบแต่ละรายการfindเป็นเพื่อนที่ดีที่นี่ แต่ Bash's forและtestเป็นเพื่อนที่ดีกว่า ... >: - D
การใช้คุณสมบัติแบบขยายของเชลล์ bash shell (ซึ่งถูกเปิดใช้งานโดยค่าเริ่มต้นในการติดตั้ง Ubuntu ปัจจุบัน)
$ tree A
A
├── B
├── C
│ ├── ac1
│ └── ac2
└── D
5 directories, 0 files
คุณสามารถระบุทุกอย่างที่ไม่รวมCและเนื้อหาโดยใช้นิพจน์ glob A/!(C)เช่น
$ echo A/!(C)
A/B A/D
ดังนั้นในการลบทุกอย่างยกเว้นไดเรกทอรีCและเนื้อหาคุณสามารถใช้
rm -rf A/!(C)
การออกจาก
$ tree A
A
└── C
├── ac1
└── ac2
3 directories, 0 files
('"เมื่อฉันเรียกใช้จากระยะไกลผ่านทางssh $VM_ADDRESS "rm -rf $APP_FOLDER/!(node_modules)"ความคิดใด ๆ ขอบคุณมาก
extglobตัวเลือก shell เปิดใช้งานสำหรับเชลล์แบบโต้ตอบเท่านั้น - ไม่แน่ใจว่าคุณสามารถบังคับsshให้ทำเช่นนั้นได้หรือไม่
วิธีง่าย ๆ อย่างหนึ่งคือการใช้ถังขยะ -ci
คุณสามารถติดตั้งได้ด้วย sudo apt-get install trash-cli
เมื่อติดตั้งแล้วคุณสามารถนำทางไปยังไดเรกทอรีหลัก A ด้วยcd /Aแล้วออกคำสั่ง
trash B Dที่ B และ D เป็นไดเรกทอรีที่คุณต้องการลบ (พวกเขาจะลงเอยในถังขยะสำหรับไดรฟ์ที่พวกเขาอยู่ดังนั้นถ้าคุณทำผิดคุณสามารถ กู้คืนไฟล์)
ทดสอบภายใต้ Ubuntu 16.04 และ 14.04
trash ! Cหรือไม่
trash: cannot trash non existent ! ''
extglobแม้ว่า
เพียงใช้การforวนซ้ำของ Bash และtestกรองไดเรกทอรีที่ต้องการและrm -rfคำสั่งเพื่อลบไดเรกทอรีซ้ำดังนี้:
for x in /path/to/parent/*; do test "$x" != "dir_survive" && rm -rf "$x"; done
iterates นี้มากกว่าองค์ประกอบทั้งหมด (ไฟล์และไดเรกทอรี) ภายในและลบองค์ประกอบซ้ำถ้าชื่อของมันคือไม่เท่ากับ/path/to/parent/ dir_surviveหากไดเรกทอรีหลักเป็นไดเรกทอรีปัจจุบันคุณอาจเขียน*เป็นเส้นทางเท่านั้น
หากคุณไม่แน่ใจและต้องการทดสอบองค์ประกอบที่จะถูกลบก่อนโดยไม่ต้องดำเนินการใด ๆ เพียงแค่แทนที่rm -rfคำสั่งในข้างต้นด้วยechoและมันจะออกเฉพาะผู้สมัครลบ
นี่คือตัวอย่างการเรียกใช้:
$ tree
.
├── dir1
│ ├── subdir1
│ │ ├── file1
│ │ └── file2
│ └── subdir2
│ ├── file1
│ └── file2
├── dir2
│ ├── subdir1
│ │ ├── file1
│ │ └── file2
│ └── subdir2
│ ├── file1
│ └── file2
└── dir_survive
├── subdir1
│ ├── file1
│ └── file2
└── subdir2
├── file1
└── file2
9 directories, 12 files
$ for x in *; do test "$x" != "dir_survive" && rm -rf "$x"; done
$ tree
.
└── dir_survive
├── subdir1
│ ├── file1
│ └── file2
└── subdir2
├── file1
└── file2
3 directories, 4 files