TL; DR: En iyi yol -exec rm
yerine kullanmaktır -delete
.
find a \( -name b -prune \) -o -type f -exec rm {} +
Açıklama:
Neden kullanmaya çalıştığınızda şikayet buluyor -delete
ile -prune
?
Kısa cevap: çünkü -delete
ima eder -depth
ve etkisiz -depth
kılar -prune
.
Uzun cevaba gelmeden önce, önce ve olmadan bulma davranışını gözlemleyin -depth
:
$ find foo/
foo/
foo/f1
foo/bar
foo/bar/b2
foo/bar/b1
foo/f2
Tek bir dizindeki siparişle ilgili hiçbir garanti yoktur. Ancak bir dizinin içeriğinden önce işleneceğine dair bir garanti vardır. foo/
Herhangi birinden önce foo/*
ve foo/bar
önce not edin foo/bar/*
.
Bu tersine çevrilebilir -depth
.
$ find foo/ -depth
foo/f2
foo/bar/b2
foo/bar/b1
foo/bar
foo/f1
foo/
Şimdi hepsinin foo/*
daha önce göründüğünü unutmayın foo/
. İle aynı foo/bar
.
Daha uzun cevap:
-prune
bulgunun bir dizine inmesini engeller. Başka bir deyişle -prune
, dizinin içeriğini atlar. Sizin durumunuzda -name b -prune
bulgunun adıyla herhangi bir dizine inmesini engeller b
.
-depth
dizinin içeriğini dizinin kendisinden önce işlemek için bulur. Bu, find'ın dizin girdisini işlemeye başlamasıyla b
, içeriğinin zaten işlendiği anlamına gelir. Dolayısıyla -prune
, -depth
etkisiyle etkisizdir .
-delete
ima -depth
o zaman boş bir dizin ilk dosyaları silmek ve böylece. -delete
boş olmayan dizinleri silmeyi reddeder. Sanırım -delete
boş olmayan dizinleri silmek ve / veya -delete
ima etmeyi önlemek için bir seçenek eklemek mümkün olurdu -depth
. Ama bu başka bir hikaye.
İstediğinizi başarmanın başka bir yolu var:
find a -not -path "*/b*" -type f -delete
Bunu hatırlamak daha kolay olabilir veya olmayabilir.
Bu komut yine de dizine iner ve içindeki b
her dosyayı yalnızca -not
reddetmek için işler . Dizin b
çok büyükse bu bir performans sorunu olabilir .
-path
farklı çalışır -name
. tüm yolla eşleşirken -name
yalnızca dosya veya dizinin adıyla eşleşir -path
. Örneğin yolu inceleyin /home/lesmana/foo/bar
. -name -bar
eşleşeceğinden addır bar
. -path "*/foo*"
dize /foo
yolda olduğu için eşleşecektir . -path
kullanmadan önce anlamanız gereken bazı karmaşıklıklar vardır. find
Daha fazla ayrıntı için sayfasının kılavuz sayfasını okuyun .
Bunun% 100 kusursuz olmadığına dikkat edin. "Yanlış pozitif" olma şansı vardır. Komutun yukarıda yazılma şekli, adın başladığı herhangi bir üst dizine b
(pozitif) sahip olan herhangi bir dosyayı atlayacaktır . Ancak b
, ağaçtaki konumdan bağımsız olarak adın başladığı tüm dosyaları atlar (yanlış pozitif). Bu, daha iyi bir ifade yazarak düzeltilebilir "*/b*"
. Bu okuyucu için bir alıştırma olarak kaldı.
Ben kullandığınız varsayalım a
ve b
daha fazlası gibi tutucuları ve gerçek isimler olarak allosaurus
ve brachiosaurus
. Eğer brachiosaurus
yerine koyarsanız b
, yanlış pozitif miktarı büyük ölçüde azalacaktır.
En azından yanlış pozitif olacak değil o trajik olarak değil olacak, böylece silindi. Ayrıca, ilk önce komutu çalıştırmadan -delete
(ancak ima edileni yerleştirmeyi unutmayın -depth
) ve çıktıyı inceleyerek yanlış pozitifleri kontrol edebilirsiniz .
find a -not -path "*/b*" -type f -depth
a
hariç her şeyi nasıl ekliyorsunuza/b
?