Bazı hariç bir dizindeki tüm dosyalar nasıl silinir?


123

Bir dizindeki tüm dosyaları silmem gerekiyor, ancak bazılarını hariç tutmam gerekiyor. Örneğin, dosyaları ile bir dizindeki a b c ... z, tüm haricinde silmenize gerek uve p. Bunu yapmanın kolay bir yolu var mı?


Aşağıdaki cevaplar çok daha iyidir, ancak dosyaları salt okunur şekilde kaydetmelerine, hepsini silmelerine ve sonra orijinal izinlerine (rm -f kullanmadığınız sürece) değiştirmelerine izin verebilirsiniz. Hangi izinleri geri yükleyeceğinizi bilmek zorunda kalacaksınız ve işlem sırasında hiçbir şeyin bunlara erişmesine gerek olmadığını bilmek zorunda kalacaksınız. Bu nedenle diğer cevaplar daha iyi.
Joe

1
Ayrıca gizli dosyaları silmek istiyorsanız çalıştırmadan shopt -s dotglobönce çalıştırın rm (...).

Yanıtlar:


108

Bu durumlarda ne yapacağım yazmaktır.

rm *

Sonra basın Ctrl+ X, *için genişletmek * tüm görünür dosya adları içine.

Sonra listeden saklamak istediğim iki dosyayı kaldırabilir ve sonunda komut satırını çalıştırabilirim.


25
Sanırım bu yalnızca *genişleyen dosyaların listesi de fazla uzun olmadıkça çalışır. : -}
Frerich Raabe

9
Esc, ardından * ile "*" genişletilir.
slowpoison

2
@SantoshKumar: Bu bana mantıklı gelmiyor. Genişletme her zaman çalışır, daha sonra hangi komutu kullanmak istediğinize bağlı değildir.
Der Hochstapler

2
@OliverSalzburg Üzgünüz, kombinasyon biraz kafa karıştırıcı. Bence Ctrl+ Shift+ x+*
Santosh Kumar gibi

2
@SantoshKumar: Ama bu kombinasyon değil.
Der Hochstapler

143

To rmtüm ama u,pbash hemen yazın:

rm !(u|p)

Bu, aşağıdaki seçenek ayarlanmasını gerektirir:

shopt -s extglob

Daha fazlasını görün: glob - Greg's Wiki


1
shopt -s extglob: Eğer olmalıdır aktif 'extglobbing'
Sparkie

18
İhtiyacın var shopt -s extglob, @Shot. Ayrıca, dizin değil sadece dosya, bu yüzden -rfkomutunuzdaki seçenekleri kaldırdım .
slhck

3
Eğer bir dosya hariç gerekirse bir seçim dosyaları, bu deneyin: rm !(index).html. Bu, "index.html" dışında ".html" ile biten tüm dosyaları siler.
mzuther

71

Kullanabilirsiniz find

find . ! -name u ! -name p -maxdepth 1 -type f -delete
  • ! sonraki ifadeyi olumsuzlar
  • -name dosya adını belirtir
  • -maxdepth 1bulma işlemini yalnızca belirtilen dizini gerçekleştirir ( findvarsayılan olarak dizinleri değiştirir)
  • -type f yalnızca dosyaları işleyecektir (örneğin, dizinleri değil)
  • -delete dosyaları silecek

Ardından bulduğunuz man sayfasına bakarak koşulları ayarlayabilirsiniz.

Güncelleme

  • İfadelerin öğelerinin sırasının önemli olduğunu unutmayın (belgelere bakın)
  • İlk önce komutunuzu kullanarak komutunuzu test edin -print.-delete

    find . ! -name u ! -name p -maxdepth 1 -type f -print

5
yüklemlerin sırası burada kritiktir. Biri felaketten -deletehemen sonra .çıkarsa (CWD'deki tüm dosyaları silecektir)
Michał Šrajer

Bu daha kompakt olarak yazılmış olabilirfind . -maxdepth 1 -type f -name '[^up]' -delete
kojiro

4
@kojiro evet, ancak yalnızca bir harf olan dosyalar için. Daha karmaşık isimlerle, regex bir karışıklık olabilir.
Matteo

2
finden iyi arkadaşım, özellikle glob için çok fazla dosya varken
Terence Johnson

43

Basit:

mvİstediğiniz dosyaları bir üst dizinde, rmdizinde ve sonra mvonları geri.


13
Offcourse, onları daha yüksek bir dizine taşıyın. Bunları silmek istediğiniz bir alt dizine
aktarmamaya çalışın

@Konerak: rmolmadan -ralt dizinleri kaldırmaz.
reinierpost

11
Bu, hedef dizinde aynı ada sahip dosyaların üzerine yazacaktır
Matteo

7
Bunu küçümsüyorum, çünkü kullanışlı olsa da atomik değildir ve kısa bir süre boyunca tüm dosyaları dizinden etkin bir şekilde kaldırır; Örneğin, dosyalar ağda paylaşılıyorsa bu kabul edilemez.
sam hocevar

15

Bu cevaba biraz benzemekle birlikte, özel bir seçeneğe ihtiyaç duyulmuyor, bildiğim kadarıyla aşağıdaki gibi herhangi bir (belli belirsiz) / bin / sh gibi kabuk (ör. Bash, zsh, ksh, vb.) Tarafından desteklenen "eski" işlevler.

rm [^up]

2
Bu 1-char dosya isimleri için çalışır. Daha uzun isimler için, sparkie'nin cevabı daha iyidir.
glenn jackman

3
Neyle yanlış olurdu rm [^up]*? Sık sık benzer şeyler yapıyorum.
33'te

3
@ MichaelKjörling - bu sadece u ve p ile başlayanları değil, u veya p ile başlayan tüm dosyaları siler. Ben OP (@Ashot) az ve u, p, vb anlamına geliyordu. sembolik ve kelimenin tam anlamıyla değil.
Sudipta Chatterjee

4
Yani tüm dosyaları silmek istiyorsunuz @HobbesofCalvin değil u ya p başlayarak olmayanlar onlarla başlayan.
rjmunro

@ rjmunro - teşekkürler, bunu kaçırdım! :)
Sudipta Chatterjee

11

Bulmadan yapmak:

ls | grep -v '(u|p)' | xargs rm

(Düzenleme: "u" ve "v", buradaki diğer yerlerde olduğu gibi, tüm regex'lerin genel sürümleri olarak kullanılıyor. Açıkçası, regex'lerinizi çok fazla eşleştirmekten kaçınmak için dikkatli tutmak isteyeceksiniz.)

Diğerlerinin önerdiği gibi, bunun çoğunu yapacaksanız, kesinlikle bir senaryo isteyeceksiniz.


grep varsayılan olarak genişletilmiş regexpt ile başa çıkmayacak: ya kullan -Eya daegrep
Matteo

2
bu, a uveya a içeren dosyaları hariç tutacaktırp
Matteo

@Matteo Hayır olmaz. Grep, dosyaları greplemiyor, ls komutunun çıktısını elliyor. Sen gibi bir şey düşünüyorlar grep -L (u|p)' * | xargs rmnerede -Lliste bir maç içermeyen filenames gelir.
rjmunro

4
Oh, adı olan uveya pa uveya a içeren hiçbir dosya içermeyen herhangi bir dosyayı kastediyorsunuz p. Bu doğru. Aşağıdakileri kullanarak düzeltebilirsinizegrep -v '^(u|p)$'
rjmunro

1
İşte bu maçlar dışındaki her şeyi kaldır! ls | grep -v 'vuze\|progs' | xargs rm -rf
Nick

6

Zsh içinde:

setopt extended_glob  # probably in your .zshrc

sonra

rm ^(u|p)

veya

rm *~(u|p)

Eğer varsa ikinci hatta çalışacak ^içinde $histcharsgeçmiş ikamesi için ve tabii ki daha önce keyfi bir topak koyabilirsiniz ~.


5

GLOBIGNORE iki nokta üst üste ayrılmış bir liste alır

GLOBIGNORE=u:p
rm *

12
Bu benim kabuğumda çalışmıyor (GNU bash 4.1.5 (1)). Önceliklerm bir test dizininden biraz daha az zararlı bir şeyle test ettiğinizden emin olun !
09'da

3

Disket çağında, "Geçici" olarak adlandırılan ve geçici olarak olayları geçerli dizinden çıkaran ve bir komutu yürüten bir çalıştırılabilir dosya vardı.

hariç * .txt del *. *

Metin dosyalarınız dışındaki her şeyi silmek için.

Bu, bir kabuk betiği olarak uygulamak için oldukça önemsiz bir şey olurdu ve eğer bu iki katından fazla yapabileceğiniz bir şeyse, iyi bir fikir gibi görünüyor.


2
Bana da aynı şeyi hatırlattı. Ancak geçici olarak klasör dışına çıkmak, çoklu görev çağında iyi bir fikir olmayabilir :)
Sedat Kapanoglu

3
 find . -maxdepth 1 ! -name "u" ! -name "p" -type f -exec rm -rf {} \;

Bu, unix içindeki p ve p dışındaki tüm dosyaları siler.


2

Tam karmaşık regexp emacs, posix-awk veya posix genişletilmiş stilde (etkilenen tüm dosya adlarını kapsayan) rasgele karmaşık dışlama desenleri belirtmeyi tercih edenler için, bunu tavsiye ederim. Bu dışlar uve pbu örnekte simdiki içinde. Bu komut dosyaları için kullanışlı olabilir.

find -regextype posix-awk ! -regex './(u|p)' -print0 | xargs -0 rm -rf

İfadeden önce bir dizin belirtmeniz gerekir (`find. -Regextype ...).
Matteo

-regextypesadece GNU versiyonlarında çalışacak
Matteo

hayır - Bulma sürümüm (debian squeeze) kesinlikle geçerli dizinin kullanılması gerekiyorsa ifadeden önce açık bir dizin gerektirmez
sparkie

@sparke: Bu sadece GNU uygulamaları üzerinde çalışıyor
Matteo

@ sparkie: dizini tanımlamaması (ilk parametre) için findGNU findkomut uzantısıdır . Aynısı -regextypeseçenek için de geçerlidir . Ek olarak, komutunuz alt dizinlerdeki dosyaları da silerken, asıl soru açıkça bir dizindeki dosyalar hakkında sorulur.
Mikko Rantalainen

1

Ben her zaman kullanırım:

rm [a-o,q-t,v-z]*

Bu, ne kadar granül yapmak istediğinizi tanımlamanıza izin verecektir. Yani bir ile o ve Z dosyalarını silmek istiyorsanız kullanabilirsiniz:

rm [a-o,z]*

1

Yine başka bir sürüm kullanarak xargs:

ls -1 | grep -v do_not_delete | xargs -I files rm "files"

Not xargs -Idoğru boşluk da dahil olmak üzere dosya idare için gereklidir.


1

Yine bir başka:

for FILE in ./*; do if [[ $FILE != ./u* ]] || [[ $FILE != ./p* ]];then rm $FILE; fi; done;

Bu biraz uzundur ve kolayca, kolayca ve argümanlı sayıda argüman barındırabilen bir fonksiyon haline getirip getiremeyeceğinizi bilmiyorum, ama iyi çalışıyor.

Ve saf bash iyiliği var.


1

İşte başka bir değişken. Yazabilirsin:

rm -i *

veya:

rm --interactive *

Bu yüzden rmsizden her dosyanın silinmesini onaylamanızı isteyecektir.


1

kullanın:

find . -type f ! -name 'u' ! -name 'p' ! -name '*.ext' -delete
find . -type d ! -name 'u' ! -name 'p' ! -name '*.ext' -delete

Dizinler dahil tüm dosyaları silmek için, u, p ve .ext dosyaları hariç.


0

Dağılması zor olan basit bir yol: diyelim ki * .pdf hariç her şeyi silmek istediğinizi:

mkdir tmp
mv *.pdf tmp
rm *
mv tmp/* .
rm -r tmp
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.