सभी लेकिन एक (या अधिक) प्रकार के फिलामेंट को निकालें


20

मैं एक फ़ोल्डर में सभी फ़ाइलों को हटाने के लिए एक कमांड को खोजने की कोशिश कर रहा हूं, लेकिन एक तरह का फ़ाइलप्राइप नहीं। लेकिन मुझे लगता है कि कोई किस्मत नहीं है। मैंने अब तक क्या प्रयास किया है:

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

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

मैं उपयोग कर रहा हूँ zsh का संस्करण है zsh 5.0.2 (x86_64-apple-darwin13.0.1)

जवाबों:


22

extended_globविकल्प आपको के अपने विस्तारित ZSH देता ग्लोब वाक्य रचना

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

आप ksh ग्लब्सksh_glob पाने का विकल्प सेट कर सकते हैं । इस बात से सावधान रहें कि सामान्य स्थिति में जहां ऋणात्मक पैटर्न शब्द में आखिरी चीज है, zsh कोष्ठक को ग्लोब क्वालीफायर के रूप में पार्स कर सकता है (यह ksh इम्यूलेशन मोड में ऐसा नहीं करता है)।

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

यह काम नहीं लगता है। जब मैं दौड़ता हूं तो rm -r secrets/!(directory)यह मांग करता रहता है number expectedया कभी-कभी यह मुझे देता हैevent not found: directory
CMCDragonkai

@CMCDragonkai "अपेक्षित संख्या" इंगित करती है कि आपने ksh_globविकल्प निर्धारित नहीं किया है । "ईवेंट नहीं मिला: निर्देशिका" इंगित करता है कि आप बैश चला रहे हैं (जो !(…)सिंटैक्स भी समझता है , लेकिन केवल बाद में shopt -s extglob)।
गिल्स एसओ- बुराई को रोकें '

जब मैं अपने ज़ीश शेल में था तो मैं बैश कैसे चल सकता था?
CMCDragonkai

मेरे लिए, setopt ksh_glob; echo !(a|b)काम करता है , जबकि setopt ksh_glob; echo !(a)("संख्या अपेक्षित") नहीं है ...
ThiefMaster

@ThiefMaster मेरे पास एक ही मुद्दा था। यह एक बग है?
कोडटावर

5

आप findअपने शेल के बजाय उपयोग कर सकते हैं :

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

से 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.

यदि आप किसी findभी कारण से उपयोग नहीं कर सकते हैं , तो इसे zsh(या अन्य गोले) के साथ करने का एक तरीका है । zshहोने के नाते zsh, ऐसा करने का एक सरल तरीका है, लेकिन जब से मैं एक bashआदमी हूं , यह वही है जो मैं आया हूं:

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

दुर्भाग्य से, जब भी मैं अपने मैक में खोज का उपयोग करता हूं, यह बिना किसी नोटिस के सिर्फ वर्तमान ज़ीश सत्र से बाहर निकलता है। क्या आपकी भी यही समस्या है ? find [Process completed]
दजंग गुयेन

1
@nxqd बिना इसके करने के तरीके के लिए अद्यतन उत्तर देखें find। मेरा सुझाव है कि आप अपने findमुद्दे के बारे में एक प्रश्न पोस्ट करें , हालांकि ऐसा नहीं होना चाहिए। यदि आप करते हैं, का आउटपुट शामिल करें type -a find
terdon

1
यहां तक ​​कि बैश में, एक सरल समाधान है:, rm !(*.dmg)के बाद shopt -s extglob
गिल्स एसओ- बुराई को रोकना '

शेल में अपने डिबगिंग सुझावों के लिए @terdon धन्यवाद। इसका आउटपुट सही प्रतीत होता है:find is a shell function find is /usr/bin/find
Dzung Nguyen

@nXqd जो सही नहीं है, वह शेल फ़ंक्शन नहीं होना चाहिए, यह केवल होना चाहिए /usr/bin/find। आपके पास एक फ़ंक्शन है जिसे findआपकी बैश कॉन्फ़िग फ़ाइलों में से एक में परिभाषित किया गया है। जब से आप OSX पर हैं, शायद यही है ~/.profile
terdon

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.