ฉันต้องการลบไดเรกทอรี 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