Hapus semua sub-direktori kecuali satu


10

Misalkan di bawah direktori saat ini, ada beberapa subdirektori, dan satu disebut A.

Bagaimana cara menghapus semua sub-direktori kecuali A dengan Bash?

Jawaban:


23

Bash telah menambah globbing (tes pertama, lalu hapus gema):

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

(Sebelum saya lupa - Anda mungkin menonaktifkan penyelesaian sejarah gaya CSH, di Bash3 ada bug saat mengabaikan! (. set + H

+1 Bash jika penuh kejutan! Terkadang mereka baik seperti ini.
Aleksandr Levchuk

Wauw memang sangat bagus! Bekerja seperti yang diharapkan. Dengan shopt | grep extAnda dapat melihat apakah plugin diaktifkan.
hazard89

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

10

Bagaimana dengan:

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

Ini menghindari beberapa "kelangkaan" kesalahan ketik pada perintah lain.


1
Memberi +1 untuk melakukan hal yang waras alih-alih berharap alatnya cukup pintar. masih, suatu malam, ketika saya baru belajar Linux, saya menyalin kernel ke / tmp sebelum melakukan kompilasi pertama saya. itu tidak berhasil, tetapi menghapus yang lama, jadi saya berkata 'tidak berkeringat, saya punya salinan' hanya untuk menemukan bahwa tugas cron tengah malam telah menghapusnya dengan setiap file yang berumur lebih dari seminggu di / tmp! saya harus mengkompilasi ulang lagi dan kali ini melakukannya dengan benar, atau tidak ada reboot untuk saya!
Javier

jawaban terbaik diposting :)
warren

3

Sesuatu seperti

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

harus dilakukan.

sunting

Seharusnya memang begitu

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

untuk mencegah findberulang di bawah A.


3
Tapi, ini juga akan menghapus sub-direktori di bawah A seperti A / foo dan A / bar, tetapi akan mempertahankan A / A.
TCampbell

Keren! Pertanyaan dan answert mendapatkan bermigrasi dari SO ke SF ... tapi saya sunting di atas hilang ...
agnul

Seharusnya lebih baik menukar maxdepth dan mengetik argumen seperti ini: find. -maxdepth 1 -type d -tidak -nama A -exec rm -ir {} \;
Spawnrider

1

saya biasanya melakukan ini dengan menjalankan perintah ls yang mendapatkannya dengan benar terlebih dahulu. Saya tidak di mesin unix, tetapi sesuatu seperti:

ls -lda "[^ A]"

Setelah Anda melakukannya dengan benar, pipa ke perintah

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

Jangan ragu untuk mengedit di atas jika ekspresi reguler saya salah ...



1

Jika Anda ingin lebih fleksibel tetapi manual, Anda dapat melakukannya:

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

Dengan begitu Anda bisa melakukan munging umum.


1

Ini satu cara. Hati-hati dengan hal semacam ini, meskipun, itu sangat kuat sehingga hanya bisa digunakan untuk kebaikan atau kejahatan ...

temukan * -tipe d | grep -v "^ A" | xargs rm -rf

1

Jangan gunakan find karena beberapa orang telah menunjukkan dengan -exec dan rm tanpa melewati -print0 untuk menemukan dan -0 ke xargs. Ini akan menjadi bingung pada nama file dengan spasi atau baris baru:

$ 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

Alih-alih gunakan find-print0 dengan xargs -0, '-exec command {} +', atau -delete jika find Anda mendukungnya.



1

Selain contoh sebelumnya:

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

Anda juga dapat melakukan:

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

untuk menghindari keharusan cd some/subdirpertama.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.