Baru-baru ini saya dihadapkan pada tugas untuk menghapus semua file / folder dalam direktori tidak termasuk yang cocok dengan pola tertentu. Jadi saya membuat perintah unix baris tunggal untuk melakukan pekerjaan. Haruskah hanya satu baris? Saya kira tidak, tapi pasti lebih dingin seperti itu!
Walaupun masalahnya cukup sederhana, saya sedikit terkejut melihat betapa rumitnya solusi saya. Inilah perintah yang saya gunakan; CATATAN: ini adalah solusi yang buruk karena tidak menangani nama file yang mengandung karakter umpan baris (yang tidak masalah dalam situasi saya).
ls | grep -v PATTERN | xargs -n1 -IREPLACE rm -rf REPLACE
Saya tidak menggunakan perintah "find" karena saya tidak ingin recurse ke folder yang cocok dengan POLA. Misalnya, pertimbangkan struktur file berikut:
file_foo.txt
first_dir
|
+--> contents
+--> ...
foo_dir
|
+--> anotherfile.txt
+--> morefiles.log
foo_file.txt
somefile.txt
Menggunakan pola "foo" hanya harus menghapus "first_dir" (dan isinya tentu saja) dan "somefile.txt" ( tidak "anotherfile.txt" atau "morefiles.log").
Pertanyaan, adakah cara yang lebih baik (lebih elegan dan benar) untuk mencapai ini?
EDIT:
Baru-baru ini menarik perhatian saya bahwa "menemukan" mungkin a lebih baik pilihan:
find * -maxdepth 0 ! -name PATTERN -print0 | xargs -0n1 rm -rf
Solusi ini tidak menangani jalur yang berisi karakter umpan baris dengan benar.
sumber
Jawaban:
Contoh-contoh berikut miliki
echo
diawali sehingga Anda dapat menguji pola sebelum benar-benar menggunakannya. Hapusecho
untuk mengaktifkanrm -rf
. Penggantirm -ri
untuk meminta konfirmasi.ksh memiliki ekstensi kecocokan negatif untuk globbing-nya:
Sintaks yang sama tersedia di pesta jika Anda mengatur
extglob
pilihan:zsh memiliki sintaksnya sendiri untuk ini:
Itu juga bisa menggunakan ksh sintaks gaya:
sumber
shopt -s extglob
ke file .bashrc saya, jadi sekarang aku s satu baris). Sempurna! Saya berjanji suara positif segera setelah reputasi saya memungkinkan.Ini satu lagi
find
larutan. Saya tidak yakin ini memiliki keunggulan nyata atas Anda, tetapi tidak perluxargs
dan memungkinkan untuk kemungkinan langka * yang diperluas ke terlalu banyak nama.Saya juga menambahkan
-type f
sehingga tidak akan mencoba untuk menghapus direktori.Peringatan:
-delete
sangat kuat. Saya memberikan salah satu file tes saya 0 izin dan perintah di atas menghapusnya tanpa ragu.sumber
-delete
dengan-print
untuk melihat apakah itu menemukan file yang Anda inginkan. Jika semuanya baik, gunakan riwayat perintah (mis. Tekan tombol atas) untuk kembali ke perintah sebelumnya untuk memastikan bahwa Anda bekerja dengan filter pencarian yang sama.find -delete
tidak akan menghapus direktori yang tidak kosong. Perhatikan juga itufind -maxdepth 1
cocok dengan "." (direktori saat ini) yang sangat buruk. Meskipun saya suka ide Anda menghilangkanxargs
, mungkin digunakanfind -exec
kalau tidak.find * -maxdepth 0 ! -name PATTERN -exec rm -rf '{}' \;
Anda dapat menggunakan contoh skrip rebol ini http://askcodegeneration.com/keep-subversion/ alih-alih yang jauh lebih dimengerti dan yang dapat mengatur interaksi pengguna seperti pemilihan dan konfirmasi folder:
sumber