Tekrarlı olarak joker karakter içeren dizinleri nasıl silerim?


51

Bir WD My Book World Edition'da SSH üzerinden çalışıyorum. Temel olarak, belirli bir dizin seviyesinde başlamak ve tekrarlayan bir şekilde tüm alt dizin eşleşmelerini kaldırmak istiyorum .Apple*. Bu konuda nasıl giderim?

denedim

rm -rf .Apple* ve rm -fR .Apple*

ne alt dizinler içinde bu isimle eşleşen dizinlerden hiçbiri silinmedi.

Yanıtlar:


73

find Bütün bir ağaç üzerinde seçmeli eylemler yapmak için çok kullanışlıdır.

find . -type f -name ".Apple*" -delete

Burada, -type fbir klasör değil, bir dosya olduğundan emin olun ve tam olarak istediğiniz gibi olmayabilir, çünkü aynı zamanda sembolik bağlantıları, soketleri ve diğer şeyleri atlayacaktır. Sen kullanabilirsiniz ! -type danlamıyla dizinleri anlamına değil, hangi, ama sonra da karakter ve blok aygıtları silebilir. Ben -typeman için sayfadaki yüklemeye bakarak öneririm find.

Kesinlikle bir joker karakterle yapmak için gelişmiş kabuk desteğine ihtiyacınız vardır. Bash v4, alt dizinleri tekrarlayarak eşleştirmenizi sağlayan bir globstarseçeneğe sahiptir **. zshve kshayrıca bu modeli desteklemektedir. Bunu kullanarak yapabilirsin rm -rf **/.Apple*. Bu POSIX standardı değildir ve çok taşınabilir değildir, bu yüzden bir komut dosyasında kullanmaktan kaçınırdım, ancak bir kerelik etkileşimli kabuk eylemi için sorun değil.


3
Alabilirim find . -type d -name .Apple*işe - tüm klasörleri listeler. Ancak, -deletesonunda eklediğimde başarısız oluyor . Sadece kullanım özeti ile geri geliyor. BusyBox v1.1.1'de çalışıyor. Bu bir fark yaratır mı?
13'te kodlanmış:

1
-deletePOSIX de değil. 90'lı yılların başında **tarafından tanıtıldı zsh. Şimdi de (görünüm kronolojik olarak) ksh93, balık, bash ve tcsh.
Stéphane Chazelas 10:14

1
+1 içinrm -rf **/.Apple*
Andriy Boyko

1
@codedog, bunun yerine -deleteişe yaramazsa işe yarar -exec rm -f {} +.
Joker

1
findSilerken ayrıntılı olabilir misiniz ? Sanırım "globstar" yöntemi bunu -vanahtar ekleyerek yapar .
Demis,

16

Ben kullanarak sorunlarla karşılaştı findile -deletekasıtlı davranışı nedeniyle find, kılavuz sayfasında belirtildiği gibi (yani bu yol, benim durumumda yapmak ./, ile başlıyorsa silmek reddederek):

 -delete

Bulunan dosyaları ve / veya dizinleri silin. Her zaman doğru döner. Bu, mevcut çalışma dizininden find ağacın altında recurses'ı çalıştırır. Yol adında "/" karakterli bir dosya adını "." İle ilişkili olarak silmeyi denemez. Güvenlik nedeniyle.
Derinlik birinci geçiş işlemi bu seçenek tarafından belirtilir.
Aşağıdaki sembolik linkler bu seçenek ile uyumlu değildir.

Bunun yerine, sadece yapabildim

find . -type d -name 'received_*_output' -exec rm -r {} +

Davan için, dünyayı alıntılamanın (yıldız işareti, *) çözüm olduğu anlaşılıyor, ancak başka birinin de benzer bir problemi olması durumunda cevabımı vermek istedim.

NOT: Önceden, cevabım aşağıdakileri yapmaktı, ama @Wildcard yorumlarda bunu yaparken güvenlik kusurlarına dikkat çekti.

find . -type d -name 'received_*_output' | xargs rm -r

1
xargsBurada kullanmak için iyi bir sebep yok. -exec rm -r {} \;veya, daha iyisi, -exec rm -r {} +özel karakter dosya isimlerinde başarısız olmadan da yapacak. Bkz. Neden döngü bulgunun çıktısı kötü oluyor?
Joker

Bunu bilmek güzel. Aşağı yukarı değmez, IMO, çünkü komut hala işi halleder, ancak performans optimizasyonu takdir edilir.
Pat

1
Sadece bir performans optimizasyonu olsaydı, sizinle aynı fikirdeydim, ama değil. Bu bir güvenlik deliği. Adlarında boşluk bulunan dosyaları doğru kullanmıyorsunuz ve kötü amaçlı hazırlanmış bir dosya adı veri kaybına neden olacak. Ayrıca bkz . Bash / POSIX mermilerinde bir değişkeni alıntılamayı unutmanın Güvenlik etkileri ; Bunlardan bazıları uygulanabilir ve en azından size bahsettiğim konuların türü hakkında fikir verebilir .
Joker

Dizininizde deneyin mkdir -p $'blah\nDocuments\n/etc\n/home\n/received__output've veri kaybı için potansiyel olmadığını düşünüyorsanız, aynı komutu tekrar çalıştırın. Veya, soru Mac OS ile ilgili olduğundan mkdir -p $'blah\nDocuments\n/Users\n/Applications\n/received__output'. ( Uyarı: Bunu yaparsanız tüm dosyalarınızı SİLECEKSİNİZ. Bu benim açımdan bir şey.)
Wildcard

0

Mümkün olan, rm / find komutunuzda yanlış bir şey olmaması, ancak giriş yapmış olduğunuz kullanıcının aslında silme izinlerine sahip olmamasıdır. Bir ls -lşeyleri izinleriyle birlikte listelemek için kullanın ; kimlerle idve groupskomutlarla birlikte olduğunuzu belirleyebilirsiniz (her ikisi de kullanılabilir olmalıdır). Bunu yapmak için "yanlış kullanıcı "ysanız, dosyaların izinlerini / sahipliğini değiştirmeniz veya başka bir kullanıcıya geçmeniz gerekir.


0

Deneyin:

shopt -s dotglob           # using Bash
printf '%s\n' ./.Apple*    # test
#rm -rf ./.Apple*    

1
dotglobburada işe yaramaz. Dotglob'un yaptıklarına bir örnek için bu sayfaya bakın .
amfetamachine

-1

Basit komut:

rm `find ./ -name '.Apple*'` -rf

İyi şanslar!


4
Bu son derece hata eğilimli, bulmak -exec anahtarı var.
Anton Barkovsky
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.