Bir (veya daha fazla) türde dosya türünün tümünü kaldır


20

Bir klasördeki tüm dosyaları kaldırmak için bir komut bulmaya çalışıyorum, ancak bir tür dosya türünü değil. Ama hiç şansım yok gibi görünüyor. Şimdiye kadar denediklerim:

set extended_glob
rm !(*.dmg)
# this returns zsh:number expected

rm ./^*.dmg
# this returns no matches found 

Kullandığım zsh sürümü zsh 5.0.2 (x86_64-apple-darwin13.0.1).

Yanıtlar:


22

Bu extended_globseçenek size zsh'ın kendi genişletilmiş glob sözdizimini verir .

setopt extended_glob
rm -- ^*.dmg
rm -- ^*.(dmg|txt)

Ksh glob alma ksh_globseçeneğini ayarlayabilirsiniz . Negatif paternin kelimedeki son şey olduğu yaygın durumda, zsh parantezleri glob niteleyicileri olarak ayrıştırabilir (bunu ksh öykünme modunda yapmaz).

setopt ksh_glob
rm -- !(*.dmg|*.txt)
setopt no_bare_glob_qual
rm -- !(*.dmg)

Bu işe yaramıyor gibi görünüyor. Ben rm -r secrets/!(directory)number expectedevent not found: directory
koştuğumda

@CMCDragonkai “beklenen sayı” ksh_globseçeneği ayarlamadığınızı gösterir . “Event not found: directory” bash çalıştırdığınızı gösterir (bu da !(…)sözdizimini de anlar , ancak bundan sonra shopt -s extglob).
Gilles 'SO- kötü olmayı bırak

Zsh kabuğumdayken bash'ı nasıl çalıştırabilirim?
CMCDragonkai

Benim için setopt ksh_glob; echo !(a|b)ise çalışır setopt ksh_glob; echo !(a)( "sayı beklenen") değil ...
ThiefMaster

@ThiefMaster Ben de aynı sorunu vardı. Bu bir hata mı?
CodeTower

5

findKabuğunuz yerine kullanabilirsiniz :

find . -mindepth 1 -maxdepth 1 ! -name "*.dmg" -delete

Gönderen man find:

   ! expr True  if  expr  is false.  This character will also usually need
          protection from interpretation by the shell.
   -name pattern
          Base of file name (the path with the leading directories removed)
          matches shell pattern pattern. 
   -delete
          Delete  files; true if removal succeeded.  If the removal failed,
          an error message is issued.  If -delete fails, find's exit status
          will be nonzero (when  it eventually exits).  Use of -delete 
          automatically turns on the -depth option.

Herhangi bir findnedenle kullanamıyorsanız , işte zsh(veya diğer kabuklarla) bunu yapmanın bir yolu var . zsholmak zsh, muhtemelen bunu yapmanın daha basit bir yolu var ama ben bir basherkek olduğum için , ben bu ile geldi:

for file in *; do if [[ ! "$file" == *.dmg ]]; then rm $file; fi; done

ne yazık ki, mac'umda bul komutunu kullandığımda, herhangi bir bildirim yapmadan mevcut zsh oturumundan çıkar. Sende de aynı problem mi var ? find [Process completed]
Dzung Nguyen

1
@nXqd olmadan yapmanın bir yolu için güncellenmiş cevaba bakın find. findSorununuzla ilgili bir soru göndermenizi öneririm , bu olmamalı. Bunu yaparsanız, çıktısını ekleyin type -a find.
terdon

1
Bash'ta bile, daha basit bir çözüm var: rm !(*.dmg)sonra shopt -s extglob.
Gilles 'SO- kötü olmayı kes'

@terdon kabuktaki hata ayıklama ipuçlarınız için teşekkür ederiz. çıktı doğru gibi görünüyor:find is a shell function find is /usr/bin/find
Dzung Nguyen

@nXqd doğru değil, bir kabuk fonksiyonu olmamalı, sadece olmalı /usr/bin/find. findBash yapılandırma dosyalarınızdan birinde tanımlanan adlı bir işleve sahipsiniz . OSX'te olduğunuz için, muhtemelen ~/.profile.
terdon

3

Dosyaları kaldırmak için başka bir yol ile find, xargsve rm:

find . -mindepth 1 -maxdepth 1 ! -name '*.dmg' -print0 | xargs -0 rm
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.