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:
-prune
mencegah find turun ke direktori. Dengan kata lain-prune
melewatkan isi direktori. Dalam kasus Anda-name b -prune
artinya ketika find mencapai direktori dengan namab
itu akan melewati direktori termasuk semua subdirektori.-depth
membuat find memproses isi direktori sebelum direktori itu sendiri. Itu berarti pada saat find dapat memproses entri direktorib
isinya sudah diproses. Jadi-prune
tidak efektif dengan-depth
berlaku.-delete
menyiratkan-depth
sehingga dapat menghapus konten terlebih dahulu dan kemudian direktori kosong.-delete
menolak 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