Saya ingin menghapus secara rekursif semua file yang tidak diakses dalam beberapa saat di folder a , kecuali semua file dalam subfolder b .
find a ( -name b -prune ) -o -type f -delete
Namun, saya mendapatkan pesan kesalahan:
find:Tindakan -delete secara otomatis mengaktifkan -kedalaman, tetapi -prune tidak
tidak melakukan apa pun saat -kedalaman berlaku. Jika Anda tetap ingin melanjutkan,
cukup gunakan opsi -depth secara eksplisit.
Menambahkan -depth menyebabkan semua file di b untuk disertakan, yang harus tidak terjadi.
Adakah yang tahu cara aman untuk membuat ini berhasil?
Jawaban yang Diterima:
salah satu caranya adalah dengan menggunakan -exec rm bukannya -delete .
find a ( -name b -prune ) -o -type f -exec rm {} +
sebagai alternatif gunakan -not -path bukannya -prune :
find a -not -path "*/b*" -type f -delete
Penjelasan mengapa -prune bertabrakan dengan -delete :
temukan keluhan saat Anda mencoba menggunakan -delete dengan -prune karena -delete menyiratkan -depth dan -depth membuat -prune tidak efektif.
amati perilaku find 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. Catatan foo/ sebelum foo/* dan foo/bar sebelum 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 sebelum foo/ . Sama dengan foo/bar .
penjelasan lebih lanjut:
-prunemencegah find turun ke direktori. Dengan kata lain-prunemelewatkan isi direktori. Dalam kasus Anda-name b -pruneartinya ketika find mencapai direktori dengan namabitu akan melewati direktori termasuk semua subdirektori.-depthmembuat find memproses isi direktori sebelum direktori itu sendiri. Itu berarti pada saat find dapat memproses entri direktoribisinya sudah diproses. Jadi-prunetidak efektif dengan-depthberlaku.-deletemenyiratkan-depthsehingga dapat menghapus konten terlebih dahulu dan kemudian direktori kosong.-deletemenolak untuk menghapus direktori yang tidak kosong.
Penjelasan metode alternatif:
find a -not -path "*/b*" -type f -delete
Ini mungkin lebih mudah diingat atau tidak.
Perintah ini masih turun ke direktori b dan memproses setiap file di dalamnya hanya untuk -not untuk menolak mereka. Ini bisa menjadi masalah kinerja jika direktori b sangat besar.
-path bekerja secara berbeda dari -name . -name hanya cocok dengan nama (file atau direktori) saat -path cocok dengan seluruh jalur. Misalnya perhatikan path /home/lesmana/foo/bar . -name bar akan cocok karena namanya bar . -path "*/foo*" akan cocok karena string /foo ada di jalan. -path memiliki beberapa seluk-beluk yang harus Anda pahami sebelum menggunakannya. Baca halaman manual find untuk lebih jelasnya.
Berhati-hatilah bahwa ini tidak 100% sangat mudah. Ada kemungkinan "positif palsu". Cara perintah ditulis di atas akan melewatkan 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 b terlepas dari posisinya di pohon (positif palsu). Ini dapat diperbaiki dengan menulis ekspresi yang lebih baik daripada "*/b*" . Yang tersisa sebagai latihan untuk pembaca.
Saya berasumsi bahwa Anda menggunakan a dan b sebagai placeholder dan nama aslinya lebih mirip allosaurus dan brachiosaurus . Jika Anda memasukkan brachiosaurus sebagai pengganti b maka jumlah positif palsu akan berkurang drastis.
Setidaknya positif palsu akan tidak dihapus, sehingga tidak akan tragis. Selanjutnya, Anda dapat memeriksa positif palsu dengan terlebih dahulu menjalankan perintah tanpa -delete (tetapi ingat untuk menempatkan -depth implied yang tersirat ) dan periksa hasilnya.
find a -not -path "*/b*" -type f -depth