Yanıtlar:
İşte muhtemelen kullanmanız gereken basit çözüm:
mv filename.gif filename.gif.keep
rm *.gif
mv filename.gif.keep filename.gif
.keep
Uzantı ile ilgili özel bir şey yok , bu sadece dosya adını geçici olarak bitmeyecek şekilde yapıyor .gif
.
Dosyayı yeniden adlandırmamanız gerekiyorsa (ve bunun önemli olduğu komut dosyası durumları vardır ):
for X in *.gif; do
if [ "$X" != "filename.gif" ]; then
rm "$X"
fi
done
Veya bu şekilde daha kısa yazabilirsiniz:
for X in *.gif; do [ "$X" != "filename.gif" ] && rm "$X"; done
Bunun find
yerine kullanmayı tercih edebilirsiniz ; Çok güçlü, sen belki daha okunabilir düşünün ve daha iyi kolları gibi karakterlerle garip dosya adları *
onlarda .
find . -maxdepth 1 -not -name 'filename.gif' -name '*.gif' -delete
-not
Operatörü okunabilirlik için kullandım , ancak POSIX uyumluluğu önemliyse - GNU find özelliğini kullanmıyorsanız veya bu bir komut dosyası içinse, başkalarına yeniden dağıtmayı veya çeşitli sistemlerde çalıştırmayı düşünüyorsunuz - kullanmak !
yerine operatörü:
find . -maxdepth 1 ! -name 'filename.gif' -name '*.gif' -delete
Hakkında kullanışlı bir şey find
, büyük / küçük harfe duyarsızlık komutunu kolayca değiştirebilmeniz ve böylece aşağıdaki gibi uzantıları olan dosyaları bulup silebilmesidir .GIF
:
find . -maxdepth 1 -not -name 'filename.gif' -iname '*.gif' -delete
Kullandığım unutmayınız -iname
yerine -name
arama modeli için *.gif
ama var olmayan için kullandım filename.gif
. Muhtemelen dosyanızın ne dendiğini tam olarak bilirsiniz ve -iname
yalnızca uzantıda değil, dosya adının herhangi bir yerinde alternatif büyük / küçük harflerle eşleşir .
Tüm bu çözümler yalnızca geçerli dizinde bulunan dosyaları siler . Geçerli dizinde bulunmayan dosyaları silmezler ve geçerli dizinin alt dizinlerinde bulunan dosyaları silmezler.
Her yerde geçerli dizini içinde yer silme dosyaları isterseniz -, kullanım (vb vardır alt dizinleri dahil ve bu alt dizinleri alt dizinleri ve dosyaları geçerli dizin veya onun soyundan herhangi içinde bulunan) find
olmadan maxdepth -1
:
find . -not -name 'filename.gif' -name '*.gif' -delete
Buna dikkat et!
Diğer değerleri de ile ayarlayabilirsiniz -maxdepth
. Örneğin, geçerli dizindeki dosyaları ve alt öğelerini ve torunlarını silmek, ancak daha derinlerini silmek için:
find . -maxdepth 3 -not -name 'filename.gif' -name '*.gif' -delete
-delete
Diğer ifadelerden önce asla birinciyi koymamaya dikkat et ! Görüyorsun -delete
ki, her zaman sonuna koydum . Baştan koyarsanız ilk önce değerlendirilir ve altındaki tüm dosyalar .
(bitmeyen .gif
dosyalar ve derin alt-alt-alt ... dizinleri dahil .
) silinir!
Daha fazla bilgi için , manuel sayfalarına bakın bash
ve sh
bu örneklerde kullanılan komutlar için: mv
, rm
, [
, ve (özellikle) find
.
find
, çok yönlü olan başka bir metot (veya metot sınıfı) hakkındaki bilgilerle genişlettim .
find
tuhaf dosya adlarını *
for-loop'dan daha iyi ele alır mı? For loop *
, çift tırnak işaretleri kullandığınız için para cezası olan dosyaları işler .
Kullanıyorsanız bash
(varsayılan kabuk), extglob
kabuk seçeneği genişletilmiş bir desen eşleştirme sözdizimi kullanmanızı sağlar. Etkinleştirmek için shopt
builtin komutunu kullanın:
shopt -s extglob
(Bu satırı dosyama eklerim .bashrc
.)
Diğer şeylerin yanı sıra !()
, parenler içinde olmayan herhangi bir desenle eşleşen operatöre erişim sağlar . Amacınız için:
rm !(filename).gif
Daha fazla bilgiyi man bash
"Desen Eşleştirme" başlığı altında bulabilirsiniz.
extglob
Etkinleştirilmesi gereken ek karmaşıklığı taşır , ancak devre dışı bırakıldığında kötü bir şey olmaz (bu durumda, bu işe yaramaz). Ve shopt -s extglob
(veya global) yapılandırma dosyalarımın hiçbirinde bulunmasam da varsayılan olarak etkin görünüyor . Kutudan çıkarmamın neden işe yaradığına dair basit bir açıklama varsa, bu cevaba eklemek isteyebilirsiniz; ya da yeni bir soru gönderebilirim.
Bir aç Terminal ile Ctrl+ Alt+ Tve türü:
find . -type f -name "*.gif" -and -not -name "filename.gif" -exec rm -vf {} \;
Arasındaki fark -delete
ve -exec rm -vf {} \;
ikinci seçeneği ile, sen nedeniyle, dosyalar kaldırılmış olduğunu görmek mümkün olacak olmasıdır -v
bayrak. Bu -delete
seçenekle yapılamayan bir şey . ( -name -delete
Dosya yazdırmak, ancak rm
birlikte -v
her dosya olsaydı ortaya koymaktadır başarıyla silindi.)
Orada GLOBIGNORE
değişkeni. Kimden man bash
:
GLOBIGNORE
A colon-separated list of patterns defining the set of filenames
to be ignored by pathname expansion. If a filename matched by a
pathname expansion pattern also matches one of the patterns in
GLOBIGNORE, it is removed from the list of matches.
Yani, basit bir yol söz GLOBGINORE
konusu dosya adına ayarlamaktır :
$ touch {a,b,c,d}.png
$ echo *.png
a.png b.png c.png d.png
$ GLOBIGNORE=c.png
$ echo *.png
a.png b.png d.png
Yani senin durumunda:
GLOBIGNORE=filename.gif; rm *.gif
Elbette GLOBIGNORE
, desen içerdiğinden, bir deseni dışlamak istediğinizde kullanabilirsiniz:
$ GLOBIGNORE='[a-c].png'; echo *.png
d.png
$ touch bd.png; GLOBIGNORE='?.png'; echo *.png
bd.png
(?!) Bir avantajı ait GLOBIGNORE
ayarladığını otomatik Dahil Olmayanlar onu .
ve..
eşleşmiş olan ve sağlayan dotglob
:
The GLOBIGNORE shell variable may be used to restrict the set of file‐
names matching a pattern. If GLOBIGNORE is set, each matching filename
that also matches one of the patterns in GLOBIGNORE is removed from the
list of matches. The filenames ``.'' and ``..'' are always ignored
when GLOBIGNORE is set and not null. However, setting GLOBIGNORE to a
non-null value has the effect of enabling the dotglob shell option, so
all other filenames beginning with a ``.'' will match. To get the old
behavior of ignoring filenames beginning with a ``.'', make ``.*'' one
of the patterns in GLOBIGNORE. The dotglob option is disabled when
GLOBIGNORE is unset.
Bu nedenle, bir dizindeki tüm dosya ve klasörleri silmenin basit bir yolu :
GLOBIGNORE=.; rm -r *
Bu *
, etkin .
olduğundan beri başlayan dosya adlarıyla eşleşecek , ancak eşleşmeyecek veya bu nedenle ana dizini bu şekilde etkilemeyeceksiniz.GLOBIGNORE
dotglob
.
..