जवाबों:
यहाँ सरल उपाय है जो आपको संभवतः उपयोग करना चाहिए:
mv filename.gif filename.gif.keep
rm *.gif
mv filename.gif.keep filename.gif
.keep
विस्तार के बारे में कुछ खास नहीं है , यह सिर्फ इसलिए बनाता है ताकि फ़ाइलनाम अस्थायी रूप से समाप्त न हो .gif
।
यदि आपको फ़ाइल का नाम नहीं बदलना चाहिए (और ऐसी स्क्रिप्टिंग स्थितियाँ हैं जहाँ यह महत्वपूर्ण है):
for X in *.gif; do
if [ "$X" != "filename.gif" ]; then
rm "$X"
fi
done
या आप इसे इस तरह छोटा लिख सकते हैं:
for X in *.gif; do [ "$X" != "filename.gif" ] && rm "$X"; done
आप find
इसके बजाय उपयोग करना पसंद कर सकते हैं ; यह बहुत शक्तिशाली है, आप इसे अधिक पठनीय मान सकते हैं , और यह उन जैसे पात्रों के साथ अजीब फ़ाइलनाम को*
बेहतर ढंग से संभालता है ।
find . -maxdepth 1 -not -name 'filename.gif' -name '*.gif' -delete
मैंने -not
ऑपरेटर को पठनीयता के लिए उपयोग किया है, लेकिन अगर POSIX अनुपालन महत्वपूर्ण है - यदि आप GNU खोज का उपयोग नहीं कर रहे हैं, या यदि यह एक स्क्रिप्ट के लिए है तो आप दूसरों को पुनर्वितरित करने या विभिन्न प्रणालियों पर चलने का इरादा रखते हैं - आपको चाहिए !
इसके बजाय ऑपरेटर का उपयोग करें :
find . -maxdepth 1 ! -name 'filename.gif' -name '*.gif' -delete
इसके बारे find
में एक आसान बात यह है कि आप केस-असंवेदनशीलता के लिए कमांड को आसानी से संशोधित कर सकते हैं, ताकि यह एक्सटेंशन जैसी फ़ाइलों को .GIF
भी ढूंढे और हटाए :
find . -maxdepth 1 -not -name 'filename.gif' -iname '*.gif' -delete
कृपया ध्यान दें कि मैंने खोज पैटर्न -iname
के -name
लिए उपयोग किया है *.gif
लेकिन मैंने इसके लिए उपयोग नहीं किया है filename.gif
। संभवतः आपको पता है कि आपकी फ़ाइल को क्या कहा जाता है, और -iname
न केवल विस्तार में , बल्कि फ़ाइल नाम में कहीं भी वैकल्पिक पूंजीकरण से मेल खाएगा ।
ये सभी समाधान केवल वर्तमान निर्देशिका में तुरंत रहने वाली फ़ाइलों को हटाते हैं । वे वर्तमान निर्देशिका में निहित फ़ाइलों को नहीं हटाते हैं, और वे उन फ़ाइलों को नहीं हटाते हैं जो वर्तमान निर्देशिका की उपनिर्देशिकाओं में रहती हैं।
यदि आप वर्तमान निर्देशिका के भीतर मौजूद सभी फ़ाइलों को हटाना चाहते हैं (जो कि उपनिर्देशिका में शामिल हैं, और उन उपनिर्देशिकाओं की उपनिर्देशिकाओं में, और इसके आगे - वर्तमान निर्देशिका या इसके किसी भी वंश में शामिल फाइलें), find
बिना उपयोग करें maxdepth -1
:
find . -not -name 'filename.gif' -name '*.gif' -delete
इससे सावधान रहें!
आप अन्य मान भी सेट कर सकते हैं -maxdepth
। उदाहरण के लिए, वर्तमान निर्देशिका और उसके बच्चों और नाती-पोतों में फ़ाइलों को हटाने के लिए, लेकिन कोई गहरा नहीं:
find . -maxdepth 3 -not -name 'filename.gif' -name '*.gif' -delete
बस सुनिश्चित करें कि आपने -delete
पहले कभी नहीं डाला , दूसरे भावों से पहले! आप देखेंगे कि मैंने हमेशा -delete
अंत में रखा है । यदि आप इसे शुरुआत में डालते हैं, तो इसका मूल्यांकन पहले किया जाएगा, और सभी फाइलों के अंतर्गत .
(जिसमें फाइलें समाप्त नहीं होती हैं .gif
और गहरी उप-उप-फ़ाइलों में फाइलें शामिल हैं .
) निर्देशिका को हटा दिया जाएगा!
अधिक जानकारी के लिए , के लिए मैनुअल पृष्ठों को देखने bash
और sh
और इन उदाहरणों में इस्तेमाल किया आज्ञाओं के लिए: mv
, rm
, [
, और (विशेष रूप से) find
।
find
, जो अत्यधिक बहुमुखी है।
find
साथ अजीब फाइलनेम को हैंडल *
के लिए बेहतर है? लूप के लिए फ़ाइलों को *
ठीक से संभालता है, क्योंकि आपने दोहरे उद्धरण चिह्नों का उपयोग किया है।
यदि आप bash
(डिफ़ॉल्ट शेल) का उपयोग कर रहे हैं , तो extglob
शेल विकल्प आपको एक विस्तारित पैटर्न सिंटैक्स का उपयोग करने की अनुमति देता है। इसे सक्षम करने के लिए, shopt
अंतर्निहित कमांड का उपयोग करें :
shopt -s extglob
(मैं उस लाइन को अपनी .bashrc
फ़ाइल में शामिल करता हूँ ।)
अन्य बातों के अलावा, यह !()
ऑपरेटर तक पहुंच प्रदान करता है , जो कि किसी भी पैटर्न से जुड़ा होता है, जो कि अंदर नहीं है। अपने उद्देश्य के लिए:
rm !(filename).gif
अधिक जानकारी man bash
"पैटर्न मिलान" के तहत उपलब्ध है ।
extglob
को सक्षम करता है, लेकिन यदि यह अक्षम है तो कुछ भी बुरा नहीं होता है (उस स्थिति में, यह काम नहीं करता है)। और यह डिफ़ॉल्ट रूप से सक्षम होने लगता है, भले ही मेरे पास shopt -s extglob
मेरी (या वैश्विक) कॉन्फ़िगरेशन फ़ाइलों में से कोई भी न हो । यदि यह मेरे लिए एक सरल स्पष्टीकरण है कि यह मेरे लिए बॉक्स से बाहर क्यों काम करता है, तो आप इसे इस उत्तर में जोड़ना चाह सकते हैं; या मैं एक नया प्रश्न पोस्ट कर सकता हूं।
एक ओपन टर्मिनल के साथ Ctrl+ Alt+ Tऔर प्रकार:
find . -type f -name "*.gif" -and -not -name "filename.gif" -exec rm -vf {} \;
के बीच का अंतर -delete
और -exec rm -vf {} \;
है कि दूसरा विकल्प के साथ, आप की वजह से, फ़ाइलों को हटा दिया गया है जो देखने में सक्षम हो जाएगा -v
झंडा। यह ऐसा कुछ है जो -delete
विकल्प के साथ नहीं किया जा सकता है । ( -name -delete
फ़ाइल नाम प्रिंट होगा, लेकिन rm
साथ -v
का पता चलता है, तो प्रत्येक फ़ाइल था सफलतापूर्वक नष्ट कर दिया।)
नहीं है GLOBIGNORE
चर। से 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.
तो, एक आसान तरीका यह GLOBGINORE
है कि सवाल में सिर्फ नाम निर्धारित किया जाए:
$ 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
तो, आपके मामले में:
GLOBIGNORE=filename.gif; rm *.gif
बेशक, चूंकि GLOBIGNORE
पैटर्न शामिल हैं, आप इसे तब भी उपयोग कर सकते हैं जब आप एक पैटर्न को बाहर करना चाहते हैं:
$ GLOBIGNORE='[a-c].png'; echo *.png
d.png
$ touch bd.png; GLOBIGNORE='?.png'; echo *.png
bd.png
इसका एक फायदा (!) यहGLOBIGNORE
है कि इसे.
..
सेट करना स्वचालित रूप से बाहर हो जाता है और मिलान होने से, और यह सक्षम करता है 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.
इसलिए, निर्देशिका में सभी फ़ाइलों और फ़ोल्डरों को हटाने का एक सरल तरीका :
GLOBIGNORE=.; rm -r *
*
के साथ शुरुआत फ़ाइल नाम से मेल खाएगी .
के बाद से, GLOBIGNORE
सक्षम dotglob
है, लेकिन यह मेल नहीं खाएगा .
या ..
है, तो आप उस तरह से मूल निर्देशिका प्रभावित नहीं करेगा।