X, Y ve Z dosyaları dışındaki bir klasördeki tüm dosyaları silme


17

Belirli bir klasörde çok sayıda dosya ve klasör var ve hepsini silmek istiyorum; ancak X, Y ve Z dosyalarını saklamak istedim.

Gibi bir şey yapabilirim bir yolu var mı: rm * | but NOT grep | X or Y or Z


Ben bunu yapacak bazı düzenli ifade kullanabilirsiniz varsayalım?
Amit

Yanıtlar:


16

Bunun yerine rm kullanımında nedeniyle, kullanımı daha kolay olabilir bulmak . Bunun gibi bir komut, tam olarak 'dosya' adlı bir dosya hariç her şeyi siler

find . \! -name 'file' -delete

Birçok sürümü globbing ve düzenli ifade eşleşmesini destekleyebilmelidir.

Ayrıca find çıktısını rm'ye de ekleyebilirsiniz.

find . \! -name '*pattern*' -print0 | xargs --null rm 

3
Ve bu dosyalar kaldırarak silinecektir tam olarak görmenizi sağlar -deletehem de dosyaların kaydedileceği şey tarafından çıkarılması -deleteve \!.
Shawn J. Goff

1
dikkatli, findözyinelemeli! yani ' desen ' ile eşleşmeyen tüm alt dizinler de silinir
Alexandre Holden Daly

Xargs yoluyla yol, içerdiği dosyalardan önce dizinleri silme girişimini önlemek için -depth'e ihtiyaç duyar. Ancak, rm dizinleri de kaldırmayacağını düşünüyorum.
kullanıcı bilinmiyor

9

İle, zsh kullanarak setopt EXTENDED_GLOBkullanarak, ~operatör ( hariç )

rm -- *~(x|y|z)

veya ^operatör (olumsuzlama):

rm -- ^(x|y|z)

Ancak, muhtemelen dosyaları başka bir yere taşımalısınız, ardından her şeyi silmelisiniz. Çok kısa sürede girmek gibi parmak kaymaları açısından çok daha güvenlidir.


5

Bash'ın sonraki sürümlerinde, extglobistediğiniz şeyi yapmak için size bir sözdizimi sağlayan kabuk seçeneği vardır (yüklü sürümünüzde olup olmadığını görmek için "Yol Adı Genişletme" altındaki man sayfanızı kontrol edin):

$ shopt -s extglob  # turn on extended globbing
$ rm !(X|Y|Z)

Test etmek için, önce silinecek dosya listesinin beklediğiniz gibi olup olmadığını görmek için rmile değiştirmenizi öneririz echo.


5
ls -1 | grep -v "^[XYZ]$" # | xargs rm -r

Uyarı: Komutu çalıştırın ve silinecek dosyalar doğruysa, tekrar çalıştırın ve "#" karma karakterini silin.

Dosya adları bundan daha karmaşıksa,

ls -1 | egrep -v "^file1$|^filename2$|^f1le$" # | xargs rm -r

Yine, önce sonuçlara bakın, ardından karma işaretini kaldırın.

Bu sürüm - yorumlarda belirtildiği gibi - bazı karakterleri kaydeder ve biraz daha net görünür.

ls -1 | egrep -v "^(file1|filename2|f1le)$" # | xargs rm -r

Ddeimeke tarafından önerilen bir düzenleme , egrepargümanı"^(file1|filename2|f1le)$"
Michael

Eğer üç dosya varsa a, bve a bilk program siler - Eğer grep parçası haline ab koyarsanız: "^[ab]$" ave bancak a b, sadece niyetlerine karşı çıktı. İkinci komut da aynısını yapacak. Üçüncüsü de. Çok, çok nadir istisnalar dışında, komut dosyalarında 'ls' kullanmamalısınız. Sadece yapma.
kullanıcı bilinmiyor

3

Saklamak istediğiniz dosyaları uzaklaştırın. Bir seviye yukarı git, klasörü sil. Klasörü yeniden oluşturun ve bu dosyaları geri taşıyın.


Acaba neden eksi? .. Aslında başkaları tarafından önerilen herhangi bir şeyden daha kolay ve daha güvenli: dosya adında bazı özel karakterleri vurarak bir ayağınızı vuramazsınız.
alex

a) X dosyanızı bir dizin yukarı taşırsınız, burada X dosyası vardır - sessizce silinir, gider. b) 'Yukarı' olmayan en üst direktesiniz. c) Var mısın senin evine, ve / home yazma izni yok. Tavsiyenizi bir senaryoya koyar ve sorunsuz bir şekilde test ederseniz ve böyle bir durumda kullanırsanız - peng!
kullanıcı bilinmiyor

2
a) Hey, 'dosyaları bir seviye yukarı taşı' dedim mi? Onları uzaklaştırın dedim. b) Yani içindeki tüm dosyaları kaldırmaya çalışıyorsun /, heh? Çok pratik değil. c) Bilgisayarınızdaki tüm dosyaları kaldırmaya çalışmak $HOMEda pratik değildir.
alex

Haklısın özür dilerim.
kullanıcı bilinmiyor

0

Bu bir OSX / MacOS çıkış kancası için bir .sh komut dosyası olarak ayarladığım şey, yeterince iyi çalışıyor.

#! /bin/bash
for dir in /PathToFolder/*
 do
    if [ ! "$dir" = "/PathToFolder/FolderToKeep1" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep2" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep3" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep4" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep5" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep6" ] ; then 
      echo ${dir}
      sudo rm -R $dir user
      dscl . -delete $dir
    fi 
  done

exit 0

0

GNU-find ile, boşsa dizinleri de kaldıran -delete anahtarını kullanabilirsiniz:

 find tmp -not -name X -not -name Y -not -name Z -delete 

X, Y veya Z bir dizinse, bu dosyalar içindeki dosyaları da siler. find tmp -maxdepth 1 -not -name X -not -name Y -not -name Z -deletebu sorunu çözmenin bir yoludur.
Gilles 'SO- kötü olmayı bırak'

Unix altındaki klasörler dosya olduğundan (her şey bir dosyadır), belki de amaçlanan budur. Soru açıkça şöyle diyor: "Belirli bir klasörde çok fazla dosya ve klasör var ve hepsini silmek istiyorum;" - ve Y'yi hariç tutmak isterseniz, Y'nin bir dizin olup olmadığını biliyorsunuzdur.
kullanıcı bilinmiyor

Bu, içinde / / dosyası tmpyoksa da silinecektir . XYZ!-not-delete
GNU'ların

@ StéphaneChazelas: Sorudan, klasörlerin (tümü) silinmesi isteniyor. Patlama maskelemeye ihtiyaç duyduğundan, yazmayı tercih ederim. Backslash'ın Alt-Gr'a ihtiyaç duyduğu alman klavye düzenine bağlı olabilir.
kullanıcı bilinmiyor
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.