Dosyaları silerken belirli dosyaları ve dizinleri hariç tutma


11

Üst düzey dizinim data. databirkaç dizin içerir ve bu dizinlerin alt dizinleri vardır. data/Bazı dizinlerde birkaç dosya dışında tüm dosyaları ve dizinleri kaldırmak gerekir .

Örneğin, veriler dizinleri 100ve 101. Sadece tutmak istiyorum a.txtve b.txtdosyaları 100/ve c.txtve d.txtdosyaları 101/diğer tüm dosyaları ve dizinleri kaldırılırken 100ve 101.

Misal:

.
├── 100
   ├── a.txt
   ├── b.txt
   ├── c.txt
   └── d.txt
└── 101
    ├── a.txt
    ├── b.txt
    ├── c.txt
    └── d.txt

Kullandığım rm -rf !(a.txt|b.txt)komutu ama otomatik olarak her dizin için bu komutu uygulayamazsınız.

Yanıtlar:


12

Daha önce öğrendiğiniz gibi, extglobaşağıdakilerle etkinleştirilen özelliği kullanabilirsiniz :

shopt -s extglob

Bu, eşleşmeleri hariç tutmanıza olanak tanır, böylece aşağıdakileri yapabilirsiniz:

rm 100/!([ab].txt) 101/!([cd].txt)

İlk önce test etmek iyi bir fikirdir echo. Bu örnek, içinde 100/olmayan a.txtya da b.txtiçinde 101/olmayan c.txtya da içinde olmayan herhangi bir şeyle eşleşecektir d.txt. Eğer için aynı kurallar 100/uygulanır 102/iyi sen mesela yapabilirsiniz gibidir:

10[02]/!([ab].txt) # or
{100,102}/!([ab].txt)

Ben sadece 100 ve 101 dizinleri için bir örnek verdim ama gerçekte alt dizinlerin sayısı yaklaşık 20'dir. Ana klasördeki her dizin adını yazmadan her dizin için yukarıdaki kodu uygulamak için bir yolu var mı?
deepblue

@deepblue Sorunuza (bunun için kesin bir örnek veriniz düzenlemek ), ne kadar özellikle belirsiz rmtutmaya hangi dosyaların bilmeli bunu belirtmek için istemiyorsanız hangi dizinleri de.
tatlı

7

Bunun için kullanabilirsiniz find. Sen testleri yadsınmamaktadır findile -notveya !. Bu, eşleşmeleri bulmak yerine hariç tutar.

Saklamak istediğiniz dosyaların üst dizinlerini, özellikle de geçerli dizini silmemeye dikkat etmelisiniz ., bu yüzden silmeden önce çıktıyı iyice okuduğunuzdan emin olun.

Örneğinize dayanarak dizinden böyle bir şey yapabilirsiniz data.

find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt"

! -path ./path/to/dirSilmekten kaçınmak istediğiniz herhangi bir yol için bir ekleyin . Gibi metakarakterleri kullanabilirsiniz *, ancak "./path*dir"istenmeyen açılımları önlemek için böyle bir ifade verdiğinizden emin olun .

findvarsayılan olarak özyinelemelidir. Burada bulamasak bile ./100, kalıpla eşleşmedikçe tüm içeriğini bulacağız [ab].txt. Saklamak istediğiniz tüm adlarla eşleşemiyorsanız başka bir test ekleyin:

! -path "./100/[ab].txt" ! -path ./100/foo

Bu bulamazsınız a.txtya b.txtya foo, ama hepsi diğer dosyaları bulacaksınız.

Ne istediğinizi gördüğünüzden emin olduğunuzda -delete, bulunan dosyaları silmek için sonuna ekleyebilirsiniz :

find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt" -delete
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.