निर्देशिका से कुछ को छोड़कर सभी फ़ाइलों को निकालें


215

उपयोग करते समय sudo rm -r, मैं निम्नलिखित के अपवाद के साथ सभी फ़ाइलों को कैसे हटा सकता हूं:

textfile.txt
backup.tar.gz
script.php
database.sql
info.txt


1
इस प्रश्न को पढ़ने के 2 तरीके हैं, और मौजूदा उत्तर दोनों व्याख्याओं को कवर करते हैं: EITHER: (a) फ़ाइलों को सीधे निर्दिष्ट निर्देशिका में स्थित निर्दिष्ट नामों के साथ संरक्षित करते हैं और - जैसे rm -rकि - सबटाइटल सहित सब कुछ हटा दें - भले ही वे हों निर्दिष्ट नामों वाली फाइलें; या: (बी) लक्ष्य निर्देशिका के पूरे उपशीर्षक को पार कर जाता है और, प्रत्येक निर्देशिका में, सूचीबद्ध नामों वाले लोगों को छोड़कर सभी फ़ाइलों को हटा दें।
mklement0

जवाबों:


219
find [path] -type f -not -name 'textfile.txt' -not -name 'backup.tar.gz' -delete

यदि आप निर्दिष्ट नहीं करते -type fहैं तो आप उन निर्देशिकाओं को भी सूचीबद्ध करेंगे, जो आप नहीं चाहते हैं।


या बहुत उपयोगी संयोजन का उपयोग करके अधिक सामान्य समाधान find | xargs:

find [path] -type f -not -name 'EXPR' -print0 | xargs -0 rm --

उदाहरण के लिए, वर्तमान निर्देशिका की सभी गैर-txt-files को हटा दें:

find . -type f -not -name '*txt' -print0 | xargs -0 rm --

print0और -0अगर वहाँ फ़ाइल नाम है कि हटा दिया जाना चाहिए में से किसी में रिक्त स्थान हैं संयोजन की जरूरत है।


2
ऐसा लगता है कि xargs की टेक्स्ट साइज़ सीमा है
frazras

26
कई पैटर्न हटाने के लिए:find . -type f -not -name '*ignore1' -not -name '*ignore2' | xargs rm
Siwei शेन multiple

5
निर्देशिकाओं के बारे में क्या? यह सभी फ़ाइलों को हटा देगा, लेकिन क्या यह फ़ोल्डर्स को हटाता है ?!
orezvani

31
"| Xargs rm" के बजाय, ढूँढें -delete पैरामीटर लेता है।
एमिल स्टेनस्ट्रॉम

1
इसके बजाय -print0 | xargs -0 rm --आप बस कर सकते हैं-delete
एंडी

151
rm !(textfile.txt|backup.tar.gz|script.php|database.sql|info.txt)

एक्सग्लोब (विस्तारित पैटर्न मिलान) को BASH में सक्षम होना चाहिए (यदि यह सक्षम नहीं है):

shopt -s extglob

2
मुझे अप्रत्याशित टोकन के पास "सिंटैक्स त्रुटि" मिलती है ('' जब मैं करता हूं shopt -s extglob; rm -rf !(README|LICENSE)। किसी भी विचार क्यों?
डेनिस

@ मुझे याद नहीं है, क्षमा करें। मैंने शायद विकल्प के findसाथ उपयोग करना समाप्त कर दिया -delete
डेनिस

यह मेरे लिए सबसे अच्छा समाधान है और यह डिफ़ॉल्ट रूप से मेरे Ubuntu 12.04.4 LTS पर दुकान की आवश्यकता के बिना काम करता है
xtian

3
@nic, @ डेनिस: वाक्यविन्यास त्रुटि बताती है कि कुछ अन्य की तुलना bashमें उपयोग किया गया था, उदाहरण के लिए dash, जहां extglobसमर्थित नहीं है। हालांकि, एक इंटरैक्टिव bash शेल में, कमांड ALSO के अनुसार काम नहीं करेगा, हालांकि विभिन्न कारणों से। इसकी कमी: shopt -s extglobITSELF द्वारा निष्पादित ; सफलता प्राप्त करें (सत्यापित करें shopt extglob), निष्पादित करें rm -rf !(README|LICENSE)। (हालांकि extglobयह अभी तक सक्षम नहीं है, इतिहास विस्तार!(...) द्वारा मूल्यांकन किया जाता है , इससे पहले कि आज्ञाओं को निष्पादित किया जाता है, क्योंकि यह संभावना विफल हो जाती है, NEITHER कमांड निष्पादित होती है, और कभी चालू नहीं होती है।)extglob
mklement0

2
@nic, @Dennis, @ mklement0: मेरे पास एक ही मुद्दा था "अप्रत्याशित टोकन के पास सिंटैक्स त्रुटि (" जब एक .sh फ़ाइल के भीतर कमांड को निष्पादित करते समय (#! / बिन / बैश) लेकिन तब नहीं जब मैं इसे कमांड में चला रहा था। लाइन इंटरफ़ेस। यह पता चला कि shopt -s extglobकमांड लाइन इंटरफ़ेस में रन के अलावा , मुझे इसे अपनी स्क्रिप्ट फ़ाइल के अंदर पुन
कनेक्ट करना

41

find . | grep -v "excluded files criteria" | xargs rm

यह सभी फाइलों को वर्तमान निर्देशिका में सूचीबद्ध करेगा, फिर उन सभी को सूचीबद्ध करेगा जो आपके मानदंड से मेल नहीं खाते (निर्देशिका मिलान नामों से सावधान रहें) और फिर उन्हें हटा दें।

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

mkdir /tmp_backup && mv textfile.txt backup.tar.gz script.php database.sql info.txt /tmp_backup/ && rm -r && mv /tmp_backup/* . && rmdir /tmp_backup

यह एक बैकअप निर्देशिका बनाएगा /tmp_backup(आपने रूट विशेषाधिकार प्राप्त किया है, ठीक है?), उस निर्देशिका में सूचीबद्ध फ़ाइलों को स्थानांतरित करें, वर्तमान निर्देशिका में पुनरावर्ती सब कुछ हटा दें (आप जानते हैं कि आप सही निर्देशिका में हैं, क्या आप?), स्थानांतरित करें वर्तमान निर्देशिका से वापस सब कुछ /tmp_backupऔर अंत में, हटाएं /tmp_backup

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

निश्चित रूप से ऐसा करने के लिए और अधिक सुंदर तरीके हैं, लेकिन यह बहुत सीधा है।


2
यह भी वास्तव में अच्छी तरह से egrep के साथ काम करता है, जैसे मध्यवर्ती लेटेक्स फ़ाइलों की सफाई के लिए:find . | egrep -v "\.tex|\.bib" | xargs rm
mtsz

अद्भुत आदेश! निर्देशिकाओं को हटाने के लिए सिर्फ rm -r
Aris

1
यदि आप केवल मौजूदा मानदंड को छोड़कर अन्य मानदंडों में से सभी को हटाना चाहते हैं: find . -maxdepth 1 | grep -v "exclude these" | xargs rm -rबहुत तेजी से काम करता है क्योंकि इसे अनावश्यक रूप से निर्देशिकाओं में नीचे ड्रिल करने की आवश्यकता नहीं है।
बिलिन्हा

पुन find: पाइपलाइन: दक्षता के मुद्दे एक तरफ (3 कमांड का उपयोग findअकेले क्या कर सकते हैं) के लिए किया जाता है , यह एम्बेडेड स्पेस वाले फ़ाइलनाम के साथ काम नहीं करेगा और संभवतः गलत फ़ाइलों को हटा देगा।
mklement0

एक कमांड जो किसी अन्य स्थान पर "टू-सेव-सेव" फाइल्स को स्टोर /tmp_backupकरता है ( यदि यह बाधित है, तो अच्छी तरह से समाप्त नहीं होता है - उपयोगकर्ता के दृष्टिकोण से, सभी फाइलें गायब हो जाती हैं, जब तक कि वे नहीं जानते कि उन्हें वापस लाने के लिए उन्हें कहाँ जाना है। । इस कारण से मैं इस प्रकार की रणनीति के पक्ष में नहीं हूं।
क्रेग मैकक्वीन

20

मान लें कि उन नामों वाली फाइलें निर्देशिका ट्री में कई स्थानों पर मौजूद हैं और आप उन सभी को संरक्षित करना चाहते हैं:

find . -type f ! -regex ".*/\(textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt\)" -delete

19

आप बैश में GLOBIGNORE पर्यावरण चर का उपयोग कर सकते हैं।

मान लीजिए कि आप php और sql को छोड़कर सभी फ़ाइलों को हटाना चाहते हैं, तो आप निम्न कार्य कर सकते हैं -

export GLOBIGNORE=*.php:*.sql
rm *
export GLOBIGNORE=

इस तरह से GLOBIGNORE सेट करना "ls *" या "rm *" जैसे वाइल्डकार्ड से php और sql को नजरअंदाज करता है। इसलिए, चर सेट करने के बाद "rm *" का उपयोग करने से केवल txt और tar.gz फ़ाइल हट जाएगी।


6
+1; GLOBIGNOREवैरिएबल को सेट करने और पुनर्स्थापित करने का एक सरल विकल्प एक (GLOBIGNORE='*.php:*.sql'; rm *)
सबस्क्रिप्शन

19

मैं उप क्वेरी सूची का उपयोग करना पसंद करता हूं:

rm -r `ls | grep -v "textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt"`

-v, --invert- मैच नॉन-मैचिंग लाइनों का चयन करें

\| सेपरेटर


1
सुरुचिपूर्ण समाधान
जोशुआ सालार

9

चूंकि किसी ने इसका उल्लेख नहीं किया है:

  • उन फ़ाइलों को कॉपी करें जिन्हें आप सुरक्षित स्थान पर हटाना नहीं चाहते हैं
  • सभी फ़ाइलों को हटा दें
  • कॉपी की गई फ़ाइलों को वापस ले जाएं

2
यह अधिक जटिल है क्योंकि आपको उन्हें वापस कॉपी करने के बाद अनुमतियों का ध्यान रखना होगा।
रोमुलस

2
@RemusAvram आप अनुमतियों को संरक्षित करने cpया rsyncसंरक्षित करने के लिए उपयुक्त स्विच का उपयोग कर सकते हैं । वैसे भी, यह सिर्फ एक वैकल्पिक विधि है (एक सुझाव के रूप में) जो ओपी के जवाब के रूप में यहां अपना स्थान रखता है।
गनीउर्फ़_गनीउरफ़

यह कई स्थितियों में उचित नहीं हो सकता है जिसमें फाइलों को बनाए रखा जाना सक्रिय रूप से अन्य प्रक्रियाओं द्वारा उपयोग किया जा रहा है। यह भी हटाया जा करने के लिए फ़ाइलों का बोझिल है बस एक छोटी उपसमुच्चय है और बड़ी संख्या में फाइलें शामिल हैं।
कोडफैस्टर

@codeforester: निश्चित। लेकिन ऐसी परिस्थितियां हैं जहां यह उचित है, हालांकि ... वास्तव में मैं वास्तव में आपकी टिप्पणी का मुद्दा नहीं देखता हूं :)
गनीउर_ग्निउरफ

6

आप इसके लिए लूप के लिए लिख सकते हैं ...%)

for x in *
do
        if [ "$x" != "exclude_criteria" ]
        then
                rm -f $x;
        fi
done;

6

ओपी के लिए थोड़ा देर से, लेकिन उम्मीद है कि किसी के लिए भी उपयोगी है जो यहां बहुत बाद में आता है ...

मुझे @awi द्वारा उत्तर मिला और @Jamie Bullock द्वारा टिप्पणी पर वास्तव में उपयोगी था। एक साधारण उपयोगिता ताकि आप अलग-अलग निर्देशिकाओं में ऐसा कर सकें जो हर बार न्यूनतम टाइपिंग के साथ अलग-अलग फ़ाइल नामों / प्रकारों की अनदेखी करते हैं:

rm_except (या जो भी आप इसे नाम देना चाहते हैं)

#!/bin/bash

ignore=""

for fignore in "$@"; do
  ignore=${ignore}"-not -name ${fignore} "
done

find . -type f $ignore -delete

पाठ फ़ाइलों और foo.bar को छोड़कर सब कुछ हटाने के लिए उदा:

rm_except *.txt foo.bar 

@Mishunika के समान है, लेकिन अगर खंड के बिना।


5

यदि आप उपयोग कर रहे हैं zshजिसकी मैं अत्यधिक अनुशंसा करता हूं।

rm -rf ^file/folder pattern to avoid

साथ में extended_glob

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

4

इसके साथ काम करने की कोशिश करना:

rm -r !(Applications|"Virtualbox VMs"|Downloads|Documents|Desktop|Public)

लेकिन रिक्त स्थान वाले नाम (हमेशा की तरह) कठिन हैं। Virtualbox\ VMsउद्धरण के बजाय के साथ भी कोशिश की । यह हमेशा उस निर्देशिका ( Virtualbox VMs) को हटाता है ।


फ़ाइलों के लिए काम नहीं करता है। rm !(myfile.txt)सभी को हटाता हैmyfile.txt
कावेरीम

shopt -s extglob@ pl1nk ने बताया कि पहले निष्पादित करना चाहिए
zhuguowei

हां, बैश में विस्तारित ग्लोबिंग ( एक्सग्लोब ) को सक्रिय करना बहुत महत्वपूर्ण है , मैं इसे दैनिक दिनचर्या के आधार पर कर रहा हूं, लैब में कुछ मैक पर: shopt -s extglobऔर फिर cd /Users/alumno/और अंत rm -rf !(Applications|Virtualbox*VMs|Downloads|Documents|Desktop|Public|Library) में यहां
ग्लोबिंग के

4

बस:

rm $(ls -I "*.txt" ) #Deletes file type except *.txt

या:

rm $(ls -I "*.txt" -I "*.pdf" ) #Deletes file types except *.txt & *.pdf

यह अनुशंसित नहीं है। पार्सिंग lsआउटपुट एक समस्या बन सकता है। विस्तृत जानकारी के लिए यहां देखें
RJ

2

फ़ाइलों को अपरिवर्तनीय बनाएं। उन्हें हटाने के लिए भी रूट की अनुमति नहीं दी जाएगी।

chattr +i textfile.txt backup.tar.gz script.php database.sql info.txt
rm *

अन्य सभी फाइलें हटा दी गई हैं।
आखिरकार आप उन्हें म्यूट कर सकते हैं।

chattr -i *

0

यह @ सिवी-शेन की टिप्पणी के समान है लेकिन आपको -oकई पैटर्न करने के लिए ध्वज की आवश्यकता है । -oध्वज के लिए 'या' खड़ा है

find . -type f -not -name '*ignore1' -o -not -name '*ignore2' | xargs rm


0

आप इसे दो कमांड दृश्यों के साथ कर सकते हैं। पहले उन फ़ाइलों के नाम के साथ एक सरणी परिभाषित करें जिन्हें आप बाहर नहीं करना चाहते हैं:

files=( backup.tar.gz script.php database.sql info.txt )

उसके बाद, उस निर्देशिका में सभी फ़ाइलों के माध्यम से लूप करें जिसे आप बाहर करना चाहते हैं, यह जाँच कर कि क्या फ़ाइल नाम उस सरणी में है जिसे आप बाहर नहीं करना चाहते हैं; अगर इसकी नहीं तो फ़ाइल को हटा दें।

for file in *; do
  if [[ ! " ${files[@]} " ~= "$file"  ]];then
    rm "$file"
  fi
done

रेगेक्स तुलना गलत है - यह किसी भी फाइल को संरक्षित करेगा जिसका नाम संरक्षित फ़ाइलों में से एक का विकल्प है (हालांकि आसपास के स्थान कुछ हद तक इसे कम करते हैं; लेकिन फ़ाइल नाम में स्थान हो सकते हैं)। आपको सभी फ़ाइलों की एक सरणी एकत्र करनी चाहिए, फिर उन फ़ाइलों को घटाएं जिन्हें आप उस सरणी से बाहर करना चाहते हैं, फिर शेष फ़ाइलों को हटा दें।
ट्रिपलए

-1

चूंकि किसी ने अभी तक इसका उल्लेख नहीं किया है, एक विशेष मामले में:

OLD_FILES=`echo *`
... create new files ...
rm -r $OLD_FILES

(या सिर्फ rm $OLD_FILES)

या

OLD_FILES=`ls *`
... create new files ...
rm -r $OLD_FILES

shopt -s nullglobयदि कुछ फ़ाइलें या तो हो सकती हैं या नहीं, तो आपको उपयोग करने की आवश्यकता हो सकती है:

SET_OLD_NULLGLOB=`shopt -p nullglob`
shopt -s nullglob
FILES=`echo *.sh *.bash`
$SET_OLD_NULLGLOB

नलगुल्ब के बिना, echo *.sh *.bash आप "a.sh b.sh * .bash" दे सकते हैं।

(यह सब कहने के बाद, मैं खुद इस जवाब को पसंद करता हूं , हालांकि यह OSX में काम नहीं करता है)


लियोनार्डो हर्मोसो का मौजूदा जवाब कम बग के साथ ऐसा करता है। यह रिक्त स्थान के साथ फ़ाइल नामों के लिए विफल हो जाएगा; किसी सरणी का उपयोग करने से उस विशेष समस्या का हल हो जाता है (और उसके निजी चर के लिए अपरकेस का उपयोग करने से भी कम महत्वपूर्ण रूप से बचा जाता है, जिसे आमतौर पर टाला जाता है)।
ट्रिपलए

-3

एक प्रत्यक्ष कमांड के लिए जाने के बजाय, कृपया आवश्यक फाइलों को वर्तमान dir के बाहर अस्थायी dir में स्थानांतरित करें। तब rm *या का उपयोग कर सभी फ़ाइलों को हटा देंrm -r *

फिर आवश्यक फ़ाइलों को वर्तमान dir में स्थानांतरित करें।


यह कई स्थितियों में उचित नहीं हो सकता है जिसमें फाइलों को बनाए रखा जाना सक्रिय रूप से अन्य प्रक्रियाओं द्वारा उपयोग किया जा रहा है। यह भी हटाया जा करने के लिए फ़ाइलों का बोझिल है बस एक छोटी उपसमुच्चय है और बड़ी संख्या में फाइलें शामिल हैं।
कोडफ्रेस्टर

-3

सब कुछ निकालें file.name:

ls -d /path/to/your/files/* |grep -v file.name|xargs rm -rf

2
यदि आपकी निर्देशिका / फ़ाइलों में स्थान या असामान्य वर्ण हैं, तो यह बुरी तरह विफल हो जाएगा और डेटा हानि हो सकती है। आपको कभी भी ls पार्स नहीं करना चाहिए। mywiki.wooledge.org/ParsingLs
RJ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.