'Çıkış' dizinine göre dizinleri nasıl silebilirim?


148

.Svn dizinlerini bulmak için aşağıdaki komutu verdim:

find . -name ".svn"

Bu bana aşağıdaki sonuçları verir:

./toto/.svn
./toto/titi/.svn
./toto/tata/.svn

rm -frDizinleri ve içeriklerini silmek için tüm bu satırları nasıl işleyebilirim ?


3
GNU bulma -deleteseçeneği vardır.
— Marco

5
Veya bulgunun -exec rm -r "{}" \;sonuna ekleyebilirsiniz - kullanırken dikkatli olun rm -r! :)
— Drav Sloan

10
@Marco Silme seçeneği dizinlerde çalışmıyor gibi görünüyor.
— Arnaud

@SuperChafouin Burada dosya ve dizinlerde mükemmel çalışıyor. Mesele şu ki, sadece emtpy dizinlerini siliyor ve siz belirttiğinizde dizinde bulunan dosyalar değil, -name ".svn"sadece .svndizinin kendisi ile eşleşiyor .svn.
— Marco

1
@ SuperChafouin ancak içinde boşluk bulunan yollar için çalışmaz (bu nedenle -execalıntı ile kullanılır "{}").
— Drav Sloan

Yanıtlar:


194

Bul, -execbulduğu her eşleşme seçeneğiyle argümanları çalıştırabilir . Bu önerilen bir mekanizmadır çünkü boşluk / yeni satırlar ve içinde diğer karakterlerin bulunduğu yolları doğru bir şekilde işleyebilirsiniz. Eğer dizinin kendisini kaldırmadan önce dizinin içeriğini silmek zorunda, bu yüzden kullanacak -rolan rmbunu başarmak için komuta.

Örneğin, aşağıdakileri yapabilirsiniz:

find . -name ".svn" -exec rm -r "{}" \;

Ayrıca, sadece bulmakta söyleyebilir dizinleri bir ekleyerek .svn adlı -type dçek:

find . -name ".svn" -type d -exec rm -r "{}" \;

Uyarı Dikkatle kullanın rm -r, klasörü ve tüm içeriğini siler.

Yalnızca boş dizinleri ve yalnızca boş dizinleri içeren dizinleri silmek isterseniz, şunu -deleteve ile yapabileceğinizi bulun -empty:

find . -name ".svn" -type d -empty -delete

22
Her zaman komutları bulduktan -type sonra çalıştırma önerileri gördüm -name, çünkü stattürü alma çağrıları pahalı. Sadece kendimi oldukça fazla sayıda dosya üzerinde denedim ve doğru gözüküyor: koşma find . -name 'foo' -type d19 saniye find . -type d -name 'foo'sürdü, 32 saniye sürdü. -typeİlk önce koşmak için yaklaşık% 50 daha uzun süre .
— 15'te

6
Bu komutu yıllardır kullanıyorum, ancak şimdi Mac'te bu dizinlerin mevcut olmadığını söyleyen hatalar alıyorum. Onları silmek olsa bile. Daha önce hiç mesaj görmedim.
— Chovy

1
@Chovy ile aynı. Bu mesajlardan kurtulmanın bir yolu var mı?
— Clément

2
@chovy @ clément Bu, findaynı anda klasörü kaldırırken diğer eşleşmeler için o klasörde görmek istediğindendir. ~ Bunu nasıl düzelteceğimi henüz bilmiyorum. ~ Kirli düzeltme:find . -name "folder-to-delete" -print0 | xargs -r0 -- rm -r
— Charlie

5
@chovy @ Clément -depthArgümanın şunu düzelttiğini düşünüyorum :find . -depth -name ".svn" -type d -exec rm -r "{}" \;
— gimboland

67

İşte bir taşınabilir hala kabul edilen cevap yolundan daha hızlı.

Bir kullanılması +yerine olarak noktalı virgül ait findkomut terminatör işlemci kullanımını optimize ediyor. Çok fazla .svnalt diziniz varsa, bu önemli olabilir :

find . -name .svn -type d -exec rm -rf {} +

Asla da unutmayın 1 gerek burada kıvırcık parantez alıntı.

1fish Kabuğu kullanmazsanız .


5
+ İle noktalı virgül arasındaki fark nedir? Neden kaşlı ayraç kullanmıyoruz?
— Shicheng Guo,

1
@ShichengGuo Noktalı virgülle, her dizin için bir rm komutu bulunur, + a ile tek bir rm komutu bulunan tüm dizinleri (veya en azından çok fazla sayıda) işler. İkinci sorunuzu anlamıyorum, kıvırcık burada diş telleri kullanılmaktadır.
— jlliagre

Sanırım @ShichengGuo neden burada kaşlı ayraçları alıntılamamız gerekmediği anlamına geliyor (@jlliagre hiçbir zaman onları alıntılamamız gerekmediğini yazdı). Şimdi bir referans bulamıyorum, ancak bunun {} yerine değiştirilen yollardan otomatik olarak çıkacağı için bunu anladım.
— Quinn Comendant

Cevap ve soru + ne yaptığı konusunda tam olarak doğru değil. Çok sayıda dosya bulunursa, ';' 'komut satırı çok uzun' hata verirdi. +, gruplar halinde bulunan ve izin verilen maksimum komut satırı uzunluğundan az olan dosyaları böler ve her parti için komutu çalıştırır.
— saat

1
@gaoithe Düzenleme yaptığınız geri alma işlemini yaptım, bu yanlış bir ifadeyle doğru ifadeyi değiştirdi. Kullanılması + gelmez kullanarak, CPU kullanımını azaltmak ; gelmez bir komutla çok uzun hatası yol açar.
— jlliagre

27

Gnu find kullandığınızı varsayalım , -deleteseçeneği kullanabilirsiniz :

find . -name test -delete

hatırlanması kolay olan.


Postanızı, komutunuzun açıklanmasıyla (veya çözümünüzü yedeklemek için belgelerle) genişletmeyi düşünün. Genellikle bir (veya iki) hat cevabı en aydınlatıcı değildir.
— HalosGhost 23.02'de

94
Bu boş olmayan dizinlerde çalışmaz.
— belacqua

2
Ayrıca Mac OS X üzerinde çalışır
— beraberlik

Bu boş olmayan klasör için işe yaramaz, ancak daha kolay ve daha güvenli bir çözümdür
— RousseauAlexandre

Seçenekler sırası çok önemlidir, bu nedenle, -sil sonuncusu olmak zorunda sırayla çalıştırır bulmak
— Jose Ignacio Centeno

13

Kullandığımda bilgisayarımda:

find . \( -name dirname -type d \) -exec rm -r '{}' ';'

Dizinler silinir ancak hatayı alıyorum:

find: ‘./dirname’: No such file or directory

Her bir dizin için.

Dizinlerim boş değil, bu yüzden -delete seçeneği benim için çalışmayacak. Bu davranışın nedenini burada buldum :

  1. / dizinindeki ilk girişi bulur (zorunlu değildir). bu, örneğin dir.1 olacaktır.
  2. 'dir.?' kalıbıyla karşılaştırır. eşleşmiyor mu Evet.
  3. find "rm -r dir.1" komutunu çalıştırır.
  4. Find dizini bulmak için dir.1 / girmeye çalışır. exec komutu hakkında hiçbir şey bilmiyor.
  5. artık dir.1 bulmuyor. ENOENT döndürür (strace çıkışına bakın)

Bunu çalışmak için kullandım:

rm -r `find . -name dirname -type d`

Bulma işleminin hala gerekli olmayan ve biraz zaman alacak, dirname adlı dizinlere tekrar girmeye çalışacağını unutmayın. Dizin yapınıza bağlı olarak, bu --depthseçeneği bulmak seçeneğiyle birlikte çalışabilirsiniz . Ayrıca, dirname / foo / dirname gibi bir dizin yapınız varsa, rm'den "Böyle bir dosya veya dizin yok" hatası alırsınız. Hataları bastırmak için stderr komutunu / dev / null dosyasına yönlendirebilir veya -f(force) bayrağını rm ile kullanabilirsiniz.


2
Kötü bir fikir: boşluk içeren dosya adı her türlü korkunç soruna neden olur
— Clément

2
Gelecekteki okuyucular için: find . -name "to-delete" -print0 | xargs -r0 -- rm -rboşluklara çarpmayan, hatasız bir versiyondur
— Charlie,


1
-prune"Böyle bir dosya veya dizin yok" hatasını önlemek için ekleyin .
— Julien Carsique

12

Bunu yapmanın daha hızlı bir yolu:

find . -name ".svn" -type d -prune -exec rm -rf '{}' '+'

Başka bir ".svn" içinde ".svn" olması durumunda.


Alt dizinlerle silinecek dizinleri bulmak istiyorsanız bu çok kullanışlı değildir.
— Alexis Wilke

5

Bash'e özgü çözüm:

shopt -s globstar
rm -r **/.svn
shopt -u globstar #optional. this will disable globstar expansion

3
Birçok dosyaya uyan glob'lerin komut satırı genişletmesi için, bu mekanizma ile eşleştirebileceğiniz dosya sayısının bir sınırı vardır. Bu limitin aşılması ile sonuçlanırbash: /bin/rm: Argument list too long
— Drav Sloan 09.09.2010

1
@DravSloan doğru, ancak bu sınır yüz binlerce dosyada. Akılda tutulması gereken bir şey, ama çoğu insan için muhtemelen bir sorun olmayacak.
— evilsoup

4

-deleteEylemin -pathtestle iyi çalıştığını öğrendim . Örneğin, asıl poster problemi üzerinde aşağıdakiler çalışılmalıdır:

find . -path '*/.svn*' -delete

Emin misiniz? -deleteima eder -depthve sistemimdeki boş olmayan dizinleri siler.
— Magnus

Tekrar test edildi ve işe yarıyor. Belki de düzeltdiğim sadece yazım hatası oldu.
— kenorb

Bu yaklaşımı da denedim ve işe yaradı - dizinler silindi.
— Allan,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.