'Çı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.