Linux'ta, bir dize içeren tüm dosyaları nasıl bulabilir ve silebilirim?


17

Dize içeren tüm dosyaları silmek istiyorum foo. Linux'ta bash kullanarak bunu nasıl yapabilirim?


bu dize dosya adıdır?
rɑːdʒɑ

3
Lütfen açıklığa kavuşturun: adı içeren dosyaları foo(örn. myfoo.jpg) Veya bayt sırasını içeren dosyaları foo(bu bayt sırasını içeren ikili dosyaları içerebilir) silmek istiyor musunuz?
Hamar

Yanıtlar:


33

İşte güvenli bir yol:

grep -lrIZ foo . | xargs -0 rm -f --
  • -l arama modeliyle eşleşen dosyaların dosya adlarını yazdırır.
  • -rfooverilen dizindeki desen için özyinelemeli arama yapar .. Bu işe yaramazsa, deneyin -R.
  • -I(büyük harf i) PDF gibi ikili dosyaların atlanmasına neden olur.
  • -Z dosya adlarının sıfır (yani nul) olarak sonlandırılmasını sağlar, böylece beyaz boşluk içeren bir ad yanlış şekilde yorumlanmaz (yani bir yerine birden çok ad olarak).
  • xargs -0dosya isimleri beslemeleri grepiçin rm -fsıfır (nul) tarafından ayıran bir deyişle, bayt (hatırlamak -Zseçeneğini grep).
  • --genellikle unutulur, ancak seçeneklerin sonunu işaretlemek ve adları ile başlayan dosyaların kaldırılmasına izin vermek çok önemlidir -.

Hangi dosyaların silinmek üzere olduğunu görmek istiyorsanız, | xargs -0 rm -f --parçayı kaldırın ve Zseçeneğini bırakın grep.

Başka bir kullanıcı , güvensiz olduğu için çalıştırmamanız gereken aşağıdaki gibi bir şey önerdi :

files=`grep foo * | cut -d: -f1`
rm -f $files         # unsafe, do not run it!

ImportantStuffSilmek ve obsolete ImportantStuffiçermediğim dosyalarım varsa foo, bu komutu çalıştırdığımda kaybederim ImportantStuff(ve değilim obsolete ImportantStuff !), Çünkü $filesyorumlandığında boşluklarda parçalanır. Bu şekilde skaler kabuk değişkenine bir dosya adı listesi koymak tehlikelidir.


17
$ find -type f -exec grep -q "foo" {} \; -exec echo rm -- {} \;

Bu, tekrarlayan dosyaları içeren dosyaları arar foo. İkincisi -execsadece ilk execbaşarılı bir şekilde çıkarsa, yani eşleşirse çalıştırılır grep. Çıkışı echodoğru görünüyorsa kurutun ve çıkarın .

Veya alternatif olarak

$ find -type f -exec grep -q "foo" {} \; -print

ve

$ find -type f -exec grep -q "foo" {} \; -delete

Lekensteyn tarafından önerildiği gibi.


4
... kısaltılabilir: find -type f -exec grep -q 'foo' {} \; -delete(tırnak işaretleri {}gereksizdir, findayrıca dosyaları silebilir.). grepNormal bir ifadeyi kabul ettiğini unutmayın . Aramak istiyorsanız foo.bar, ya bundan kaçın ya -Fda kalıbı gerçek olarak kabul etme seçeneğini iletin.
Lekensteyn

kullanmak için herhangi bir neden -exec echo rm "{}" \;değil -deletemi?
vartec

1
@vartec Hayır, kullanırdım -delete. İkincisi -execve yankı yerinde iken göstermek daha kolaydır .
Adrian Frühwirth

1
Yazmak -print(veya -lsdaha fazla ayrıntı için) daha kolaydır -exec echo rm "{}" \'. Harici yardımcı programlara gerek yoktur.
Lekensteyn

1
rm {} kullanıyorsanız, rm - {} kullanın, böylece dosya adındaki özel karakterler enterpolasyona girmez. Örneğin, yazma izninizin olduğu herhangi bir dizinde '-rf /' simgesine dokunun ...
atk

1

Adrian'ın söylediklerini yaparım,

Ama "gıda" içeren dosyaları yanlışlıkla silmemek için foo etrafına kelime sınırları eklerdim (yiyecek içeren her şeyi silmediğiniz sürece.)

 $ find -type f -exec grep -q "\<foo\>" {} \; -delete

acutally, ben silmeden önce gözden olabilir böylece silmeden önce çıktı yönlendirirsiniz:

 $ find -type f -exec grep -q "\<foo\>" > /tmp/list_of_files_to_delete

Yorum yazabildiğiniz anda, bunun gibi şeyleri yorum olarak göndermelisiniz.
FSMaxB

evet önce denedim ama sonra yorum göndermeme izin verilmediğimi fark ettim.
Petter H
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.