कुछ को छोड़कर एक निर्देशिका में सभी फ़ाइलों को हटाने के लिए कैसे?


123

मुझे एक निर्देशिका में सभी फ़ाइलों को हटाने की आवश्यकता है, लेकिन उनमें से कुछ को बाहर करें। उदाहरण के लिए, फ़ाइलों के साथ एक निर्देशिका में a b c ... z, मुझे छोड़कर सभी को हटाने की आवश्यकता है uऔर p। क्या इसे करने का कोई आसान तरीका है?


नीचे दिए गए उत्तर बहुत बेहतर हैं, लेकिन आप केवल पढ़ने के लिए फ़ाइलें सहेज सकते हैं, सभी को हटा सकते हैं, और फिर उन्हें उनकी मूल अनुमतियों में बदल सकते हैं (जब तक आप rm -f का उपयोग नहीं करते हैं)। आपको यह जानना होगा कि किन अनुमतियों को पुनर्स्थापित करना है और आपको यह जानना होगा कि प्रक्रिया के दौरान कुछ भी लिखने की आवश्यकता नहीं है। यही कारण है कि अन्य उत्तर बेहतर हैं।
जो

1
अगर आप भी दौड़ने shopt -s dotglobसे पहले छुपी हुई फाइलों को हटाना चाहते हैं rm (...)

जवाबों:


108

मैं उन मामलों में क्या करता हूं टाइप करना है

rm *

तब मैं प्रेस Ctrl+ X, *करने के लिए विस्तार * सभी दृश्य फ़ाइल नाम में।

तब मैं सिर्फ उन दो फाइलों को हटा सकता हूं जिन्हें मैं सूची से रखना पसंद करता हूं और अंत में कमांड लाइन निष्पादित करता हूं।


25
मुझे लगता है कि यह केवल तब तक काम करता है जब तक कि फाइलों की सूची *बहुत लंबी नहीं हो जाती। : -}
Frerich Raabe

9
Esc इसके बाद * * "" का भी विस्तार करेगा।
धीमी गति

2
@ संतोशकुमार: इससे मुझे कोई मतलब नहीं है। विस्तार हमेशा काम करेगा, यह इस बात पर निर्भर नहीं करता है कि आप बाद में किस कमांड का उपयोग करना चाहते हैं।
डेर होकस्टापलर

2
@OliverSalzburg क्षमा करें, संयोजन थोड़ा भ्रमित है। मुझे लगता है कि आप की तरह लिखना चाहिए Ctrl+ Shift+ x+*
संतोष कुमार

2
@ संतोष कुमार: लेकिन यह संयोजन नहीं है।
डेर होकस्टाप्लर

143

करने के लिए rmसभी लेकिन u,pपार्टी में सिर्फ टाइप करें:

rm !(u|p)

इसके लिए निम्नलिखित विकल्प की आवश्यकता होती है:

shopt -s extglob

और देखें: ग्लोब - ग्रेग का विकी


1
आपके पास 'एक्सग्लोबिंग' सक्रिय होना चाहिए: शॉप
एस

18
आपको shopt -s extglob@Ashot करने की जरूरत है । इसके अलावा, यह सिर्फ फाइलें हैं, निर्देशिका नहीं, यही वजह है कि मैंने -rfआपके आदेश में विकल्प हटा दिए हैं ।
13

3
यदि आपको फ़ाइलों के चयन की एक फ़ाइल को बाहर करने की आवश्यकता है , तो यह प्रयास करें rm !(index).html:। यह "index.html" के अपवाद के साथ ".html" में समाप्त होने वाली सभी फ़ाइलों को हटा देगा।
mzuther

71

आप उपयोग कर सकते हैं find

find . ! -name u ! -name p -maxdepth 1 -type f -delete
  • ! अगले एक्सप्रेशन को नकारता है
  • -name एक फ़ाइल नाम निर्दिष्ट करता है
  • -maxdepth 1केवल निर्दिष्ट निर्देशिका findद्वारा प्रक्रिया खोजेंगे ( डिफ़ॉल्ट ट्रैवर्स निर्देशिका द्वारा)
  • -type f केवल फाइलों को प्रोसेस करेगा (और उदाहरण निर्देशिकाओं के लिए नहीं)
  • -delete फ़ाइलों को हटा देगा

फिर आप खोज के मैन पेज को देखते हुए शर्तों को ट्यून कर सकते हैं

अपडेट करें

  • ध्यान रखें कि भावों के तत्वों का क्रम महत्वपूर्ण है (प्रलेखन देखें)
  • के -printबजाय का उपयोग करके पहले अपने आदेश का परीक्षण करें-delete

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

5
विधेय का क्रम यहाँ महत्वपूर्ण है। एक डाल तो -deleteबस के बाद .यह आपदा हो जाएगा (CWD में सभी फाइलों को नष्ट करेगा)
मीकल Šrajer

इसे और अधिक कॉम्पैक्ट रूप से लिखा जा सकता हैfind . -maxdepth 1 -type f -name '[^up]' -delete
kojiro

4
@kojiro हां, लेकिन केवल उन फ़ाइलों के लिए जो सिर्फ एक अक्षर हैं। अधिक जटिल नामों के साथ रेगेक्स एक गड़बड़ हो सकता है।
मट्टेयो

2
findमेरा सबसे अच्छा दोस्त है, खासकर जब ग्लोब के लिए बहुत सारी फाइलें हैं
टेरेंस जॉनसन

43

सरल:

mvफ़ाइलों को आप एक ऊपरी निर्देशिका में चाहते हैं, rmनिर्देशिका और फिर mvउन्हें वापस।


13
ऑफकोर्स, उन्हें एक निर्देशिका उच्च करने के लिए mv। आप उन्हें हटा रहे हैं एक उपनिर्देशिका के लिए उन्हें mv नहीं करने की कोशिश ...
Konerak

@Konerak: उपनिर्देशिका को हटाए rmबिना -rनहीं होगा।
रीइनियरिएपोस्ट

11
यह गंतव्य निर्देशिका में समान नाम वाली फाइलों को अधिलेखित कर देगा
Matteo

7
मैं इसे कम कर रहा हूं क्योंकि जब यह काम हो सकता है, तो यह गैर-परमाणु भी है और प्रभावी रूप से थोड़े समय के दौरान निर्देशिका से सभी फाइलों को हटा देता है; यह स्वीकार्य नहीं होगा यदि, उदाहरण के लिए, फ़ाइलें नेटवर्क पर साझा की जा रही हैं।
सम होसेवार १०'१३ को

15

इस उत्तर के समान, लेकिन कोई विशेष विकल्प की आवश्यकता नहीं है, जहाँ तक मुझे पता है कि निम्नलिखित "प्राचीन" कार्यक्षमता किसी (अस्पष्ट) / बिन / श सदृश खोल (जैसे bash, zsh, ksh, आदि) द्वारा समर्थित है।

rm [^up]

2
यह 1-char फ़ाइलनाम के लिए काम करता है। लंबे नामों के लिए, स्पार्की का जवाब बेहतर है।
बजे ग्लेन जैकमैन

3
इसमें क्या गलत होगा rm [^up]*? मैं अक्सर ऐसी ही चीजें करता हूं।
बजे एक CVn

3
@ माइकलकॉर्जलिंग - यह यू या पी के साथ शुरू होने वाली सभी फ़ाइलों को हटा देगा, न कि केवल उन नामों और यू के साथ। मुझे लगता है कि ओपी (@Ashot) का मतलब अज़ और यू, पी, आदि था। प्रतीकात्मक और शाब्दिक रूप से नहीं।
सुदीप्त चटर्जी

4
यही कारण है कि हटाना होगा @HobbesofCalvin सभी फाइलों को नहीं यू या पी के साथ शुरुआत, नहीं उन उन लोगों के साथ इसकी शुरुआत हुई।
rjmunro

@rjmunro - धन्यवाद, उस एक को याद किया! :)
सुदिप्ता चटर्जी

11

इसे बिना खोजे:

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

(संपादित करें: "u" और "v", जैसे अन्य स्थानों में, पूरे रेगेक्स के सामान्य संस्करणों के रूप में उपयोग किया जा रहा है। जाहिर है आप बहुत सी चीजों से मेल खाने से बचने के लिए अपने रेगीक्स को लंगर डालना सावधान रहना चाहेंगे।)

आप निश्चित रूप से एक स्क्रिप्ट चाहते हैं यदि आप ऐसा करने जा रहे हैं, जैसा कि अन्य ने सुझाव दिया है।


grep डिफ़ॉल्ट रूप से विस्तारित रेग्जाप्ट को हैंडल नहीं करेगा: या तो उपयोग करें -Eयाegrep
Matteo

2
यह up
मैटो

@Matteo नहीं यह नहीं होगा। Grep फाइलों को पकड़ नहीं रहा है, यह ls कमांड के आउटपुट को पकड़ रहा है। आप कुछ ऐसा सोच रहे हैं, grep -L (u|p)' * | xargs rmजहाँ -Lसूची फ़ाइलनाम का मिलान न हो।
rjmunro

4
ओह, आपका मतलब है कि किसी भी फ़ाइल में किसका नाम है uया pनहीं, किसी भी फाइल में एक uया एक फाइल नहीं है p। वह सही है। आप का उपयोग करके ठीक कर सकते हैंegrep -v '^(u|p)$'
rjmunro

1
यहाँ इन मैचों को छोड़कर सब कुछ हटा दिया गया है! ls | grep -v 'vuze\|progs' | xargs rm -rf
निक

6

Zsh में:

setopt extended_glob  # probably in your .zshrc

फिर

rm ^(u|p)

या

rm *~(u|p)

यदि आपके पास दूसरे भी काम करेंगे ^में $histcharsइतिहास प्रतिस्थापन के लिए, और निश्चित रूप से आप से पहले एक मनमाना ग्लोब रख सकते हैं ~


5

GLOBIGNORE एक बृहदान्त्र-पृथक सूची लेता है

GLOBIGNORE=u:p
rm *

12
यह मेरे शेल (GNU बैश 4.1.5 (1)) पर काम नहीं करता है। परीक्षण से पहलेrm या परीक्षण निर्देशिका की तुलना में कुछ कम हानिकारक के साथ इसे पहले परीक्षण करना सुनिश्चित करें !
एक सीवीएन

3

फ्लॉपी युग में मेरे पास "छोड़कर" नामक एक डोज़ निष्पादन योग्य था जो वर्तमान निर्देशिका से चीजों को अस्थायी रूप से बाहर ले जाएगा और एक कमांड निष्पादित करेगा, इसलिए आप कह सकते हैं:

* .txt डेल * को छोड़कर। *

अपनी पाठ फ़ाइलों के लिए सब कुछ हटाने के लिए।

यह एक शेल स्क्रिप्ट के रूप में लागू करने के लिए एक बहुत ही मामूली बात होगी और अगर इस तरह की बात है तो आपको दो बार से अधिक करने की संभावना है, ऐसा लगता है कि यह एक अच्छा विचार होगा।


2
इसने मुझे वही बात याद दिला दी। लेकिन अस्थायी रूप से फ़ोल्डर से बाहर जाना मल्टीटास्किंग के युग में एक अच्छा विचार नहीं हो सकता है :)
सेदात कोपनोग्लू

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

यह यूएक्स और पी को छोड़कर सभी फाइलों को यूनिक्स में हटा देगा


2

उन लोगों के लिए जो एक पूर्ण विकसित रेगेक्स एमएसीएस, पॉज़िक्स-ऑक या पॉज़िक्स-विस्तारित शैली (देखें मैन पेज देखें) में मनमाना कॉम्प्लेक्स अपवर्जित पैटर्न (सभी प्रभावित फाइलनामों को फैलाना) को निर्दिष्ट करना चाहते हैं (मैं मैन पेज ढूंढता हूं) मैं इसे सुझाऊंगा। यह इस उदाहरण में uऔर pवर्तमान dir में शामिल नहीं है । यह स्क्रिप्ट के लिए उपयोगी हो सकता है।

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

आपको अभिव्यक्ति से पहले एक निर्देशिका निर्दिष्ट करने की आवश्यकता है (`खोजें। -regextype ...)।
मत्तेओ

-regextypeकेवल GNU संस्करणों पर काम करेगा
Matteo

नहीं - मेरे खोज संस्करण (डेबियन निचोड़) को निश्चित रूप से अभिव्यक्ति से पहले एक स्पष्ट निर्देशिका की आवश्यकता नहीं है यदि वर्तमान निर्देशिका का उपयोग किया जाना चाहिए
स्पार्कली

@sparke: यह सिर्फ GNU कार्यान्वयन पर काम करता है
Matteo

@sparkie: निर्देशिका के लिए (पहला पैरामीटर) को परिभाषित नहीं करना कमांड findका GNU एक्सटेंशन है find-regextypeविकल्प के लिए भी यही बात लागू होती है। इसके अलावा, आपका आदेश उपनिर्देशिकाओं में भी फ़ाइलों को हटा देगा, जबकि मूल प्रश्न एक निर्देशिका में फ़ाइलों के बारे में स्पष्ट रूप से पूछा गया था।
मिकको रैंटलैनेन

1

मैं हमेशा उपयोग करता हूं:

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

यह आपको परिभाषित करने की अनुमति देगा कि आप इसे कैसे दानेदार बनाना चाहते हैं। इसलिए यदि आप ओ और जेड फ़ाइलों के माध्यम से हटाना चाहते हैं, तो आप इसका उपयोग कर सकते हैं:

rm [a-o,z]*

1

अभी तक एक और संस्करण का उपयोग कर xargs:

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

ध्यान दें कि xargs -Iरिक्त स्थान सहित फ़ाइल नाम को संभालने के लिए आवश्यक है।


1

अभी तक एक और:

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

यह लंबा चौड़ा है और मुझे नहीं पता कि क्या आप आसानी से इसे एक फंक्शन में बना सकते हैं जो आसानी से समायोजित हो सकता है और मनमानी संख्या को तर्क दे सकता है, लेकिन यह अच्छी तरह से काम करता है।

और यह शुद्ध बैश अच्छाई है।


1

यहाँ एक और संस्करण है। आपको लिखना आता है:

rm -i *

या:

rm --interactive *

तो rmआपको प्रत्येक फ़ाइल को हटाने की पुष्टि करने के लिए कहेंगे।


1

उपयोग:

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

U, p और .ext फ़ाइलों को छोड़कर, निर्देशिकाओं सहित सभी फ़ाइलों को हटाने के लिए।


0

एक आसान तरीका जो गड़बड़ करना मुश्किल है: मान लें कि आप * .pdf को छोड़कर सब कुछ हटाना चाहते हैं:

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