TL; DR: cara terbaik adalah menggunakan -exec rmalih-alih -delete.
find a \( -name b -prune \) -o -type f -exec rm {} +
Penjelasan:
Mengapa menemukan mengeluh ketika Anda mencoba untuk menggunakan -deletedengan -prune?
Jawaban singkat: karena -deletemenyiratkan -depthdan -depthmembuat -prunetidak efektif.
Sebelum kita sampai pada jawaban panjang, pertama-tama amati perilaku menemukan dengan dan tanpa -depth:
$ find foo/
foo/
foo/f1
foo/bar
foo/bar/b2
foo/bar/b1
foo/f2
Tidak ada jaminan tentang pesanan dalam satu direktori. Tetapi ada jaminan bahwa direktori diproses sebelum isinya. Catat foo/sebelum foo/*dan foo/barsebelum apa pun foo/bar/*.
Ini dapat dibalik dengan -depth.
$ find foo/ -depth
foo/f2
foo/bar/b2
foo/bar/b1
foo/bar
foo/f1
foo/
Perhatikan bahwa sekarang semua foo/*muncul sebelumnya foo/. Sama dengan foo/bar.
Jawaban yang lebih panjang:
-prunemencegah menemukan turun ke direktori. Dengan kata lain -prunemelompati isi direktori. Dalam kasus Anda, -name b -prunemencegah menemukan turun ke direktori apa pun dengan nama b.
-depthmake find untuk memproses isi direktori sebelum direktori itu sendiri. Itu berarti pada saat ditemukan dapat memproses entri direktori bisinya telah diproses. Dengan demikian -prunetidak efektif dengan -depthefeknya.
-deletetersirat -depthsehingga dapat menghapus file pertama dan kemudian direktori kosong. -deletemenolak untuk menghapus direktori yang tidak kosong. Saya kira itu akan mungkin untuk menambahkan pilihan untuk kekuatan -deleteuntuk menghapus direktori yang tidak kosong dan / atau untuk mencegah -deletemenyiratkan -depth. Tapi itu cerita lain.
Ada cara lain untuk mencapai apa yang Anda inginkan:
find a -not -path "*/b*" -type f -delete
Ini mungkin atau mungkin tidak mudah diingat.
Perintah ini masih turun ke direktori bdan memproses setiap file di dalamnya hanya untuk -notmenolaknya. Ini bisa menjadi masalah kinerja jika direktori bsangat besar.
-pathbekerja berbeda dari -name. -namehanya cocok dengan nama (file atau direktori) saat -pathcocok dengan seluruh jalur. Misalnya mengamati jalannya /home/lesmana/foo/bar. -name -barakan cocok karena namanya bar. -path "*/foo*"akan cocok karena string /fooada di jalur. -pathmemiliki beberapa seluk yang harus Anda pahami sebelum menggunakannya. Baca halaman manual finduntuk lebih jelasnya.
Berhati-hatilah karena ini bukan 100% sangat mudah. Ada kemungkinan "false positive". Cara perintah ditulis di atas akan melewati file apa pun yang memiliki direktori induk yang namanya dimulai dengan b(positif). Tapi itu juga akan melewatkan file apa pun yang namanya dimulai dengan bterlepas dari posisi di pohon (false positive). Ini dapat diperbaiki dengan menulis ekspresi yang lebih baik daripada "*/b*". Itu dibiarkan sebagai latihan untuk pembaca.
Saya berasumsi bahwa Anda menggunakan adan bsebagai placeholder dan nama asli lebih mirip allosaurusdan brachiosaurus. Jika Anda meletakkan brachiosaurusdi tempat bmaka jumlah positif palsu akan berkurang drastis.
Setidaknya positif palsu tidak akan dihapus, sehingga tidak akan tragis. Selanjutnya, Anda dapat memeriksa positif palsu dengan terlebih dahulu menjalankan perintah tanpa -delete(tapi ingat untuk menempatkan yang tersirat -depth) dan memeriksa hasilnya.
find a -not -path "*/b*" -type f -depth
akecualia/b?