एक फ़ाइल को छोड़कर सभी फ़ाइलों / निर्देशिकाओं को हटा दें


243

मेरे पास एक निर्देशिका है जिसमें बड़ी संख्या में फाइलें हैं। मैं फ़ाइल को छोड़कर सभी फ़ाइलों को हटाना चाहता हूँ। मैं यह कैसे करु?

व्यक्तिगत रूप से अवांछित लोगों को हटाने के लिए बहुत सी फाइलें हैं और इस एक फाइल को छोड़कर उन सभी को निकालने के लिए उनके नाम * का उपयोग करने के लिए बहुत विविध हैं।

किसी ने उपयोग करने का सुझाव दिया

rm !(file.txt)

लेकिन यह काम नहीं करता है। यह रिटर्न:

Badly placed ()'s 

मेरा OS साइंटिफिक लिनक्स 6 है।

कोई विचार?


13
जिसे आप रखना चाहते हैं उसे स्थानांतरित करें, फिर दूसरों को आरएम करें?
ओलिवियर दुलाक

5
@OlivierDulac क्या हम इस सवाल में केवल दो लोग हैं जो सवाल को खत्म नहीं कर रहे हैं?
शादुर

1
@ शादुर: ठीक है, मैं उनसे संबंधित कर सकता हूं: ऑनलाइनर आकर्षक हैं ... ^ ^
ओलिवियर

1
धन्यवाद, और हाँ मैं एक-लाइन समाधान की तलाश में था। यह बहुत समय लग रहा है के रूप में चारों ओर चल फ़ाइलें रखने के लिए के रूप में मुझे यह अक्सर करना है।
कांटुरा

जवाबों:


287

POSIXly:

find . ! -name 'file.txt' -type f -exec rm -f {} +

को छोड़कर सभी नियमित फ़ाइलों (पुनरावर्ती, छिपे हुए सहित) को हटा देगा file.txt। निर्देशिका को निकालने के लिए बदलने -type fके लिए -type dऔर जोड़ने -rके लिए विकल्प rm

में bash, उपयोग करने के लिए rm -- !(file.txt)है, तो आप चाहिए extglob सक्षम :

$ shopt -s extglob 
$ rm -- !(file.txt)

(या कॉलिंग bash -O extglob)

ध्यान दें कि extglobकेवल bashऔर कोर्न शेल परिवार में काम करता है । और उपयोग करने से त्रुटि rm -- !(file.txt)हो सकती है Argument list too long

में zsh, आप उपयोग कर सकते हैं ^पैटर्न नकारना के साथ extendedglob सक्षम:

$ setopt extendedglob
$ rm -- ^file.txt

या के साथ एक ही सिंटैक्स का उपयोग kshऔर bashविकल्पों के साथ ksh_globऔर no_bare_glob_qualसक्षम होना चाहिए।


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

11
मैं -deleteइसके बजाय सुझाव देना चाहता हूं -exec, छोटे और आसान याद करने के लिए
इज़्काटा

6
@ इज़काटा: -deleteपोसिक्स द्वारा परिभाषित नहीं है।
cuonglm

5
फ़ाइलों की सूची को बाहर कैसे करें?
मयसम

5
@ मायसम - एक समाधान के लिए मेरा जवाब देखें जो फाइलों की एक सूची को संभाल लेगा। Gnouc के findसमाधान के साथ आप कर सकते हैं ! \( -name one_file -o -name two_file \)और इतने पर।
15

112

एक और अलग दिशा में ले जाता है (यदि फ़ाइल नामों में कोई स्थान नहीं है)

ls | grep -v file.txt | xargs rm

या (फ़ाइल नामों में स्थान होने पर भी काम करता है)

ls | grep -v file.txt | parallel rm

से man grep:

 -v, --invert-match
          Invert the sense of matching, to select non-matching lines.  (-v is specified by POSIX)

2
यह काम नहीं करेगा अगर फ़ाइल नामों में एक स्थान है ...
Matteo

1
Ciao @Matteo, यह रिक्त स्थान वाली फ़ाइलों के लिए भी काम करता है, लेकिन आपको उद्धरणों, उदाहरण के लिए grep- पैटर्न को घेरना होगा ls | grep -v "a file with spaces.bin" | xargs rm। यह सामान्य grepवाक्य रचना है।
सेबेस्टियन

1
समस्या @Sebastian नहीं है grepलेकिन rmrmअंतरिक्ष से अलग तर्कों की एक सूची मिलेगी। कोशिश करें touch 'a b'; touch 'c d'; ls | grep -v 'a b' | xargs rm: आपको मिलेगा rm: c: No such file or directoryऔरrm: d: No such file or directory
मैटो

1
हां, यह एक आम समस्या है। -print0इन findऔर -0इन विकल्पों को देखें xargs। यहाँ एक समाधान है, लेकिन थोड़ा असुविधाजनक है। find . -maxdepth 1 -type f | grep -v 'a b' | tr '\n' '\0' | xargs -0 rm। वैसे, ग्नू parallelइस कुएं को संभालता है (मैं लगभग हमेशा इसे xargs के विकल्प के रूप में उपयोग करता हूं:ls | grep -v 'a b' | parallel rm
सेबस्टियन

1
यह न केवल रिक्त स्थान है, यह सभी रिक्त और newlines है, लेकिन पात्रों (एकल, दोहरे उद्धरण और बैकस्लैश) और फ़ाइलनाम के साथ भी उद्धृत कर रहा है -
स्टीफन चेज़लस

32

प्रतिलिपि बनाए रखें, सब कुछ हटाएं, प्रतिलिपि को पुनर्स्थापित करें:

{   rm -rf *
    tar -x
} <<TAR
$(tar -c $one_file)
TAR

एक पंक्ति में:

{ rm -rf *; tar -x; } <<< $(tar -c $one_file)

लेकिन इसके लिए एक शेल की आवश्यकता होती है जो यहां के तारों का समर्थन करता है।


10
यह कुछ हद तक दिमाग उड़ाने वाला है।
vschum

2
@ डेरेक - कृपया संपादन देखें।
मोकेसर 2

2
लेकिन अगर यह आधे रास्ते से बाधित हो जाता है, या कुछ और गलत हो जाता है, तो फ़ाइल चली जाती है।
कैस्पर

2
@kasperd - नहीं। माता-पिता खोल समय के बीच मर जाता है सिर्फ अगर इसे चलाता rmहै और tar -xrmजितना चाहे उतना असफल हो सकता है।
mikeserv

2
इसे किसी अन्य निर्देशिका में स्थानांतरित करने और इसे वापस ले जाने के लिए अधिक कुशल नहीं है? हमें केवल इसके पथ के साथ, फ़ाइल की सामग्री से निपटने की आवश्यकता नहीं है।
15

23

तुम सब इस पर काबू पा रहे हो।

cd ..
mv fulldir/file.txt /tmp/
rm -rf fulldir
mkdir fulldir
mv /tmp/file.txt fulldir/

किया हुआ।

संपादित करें वास्तव में, आसान:

cd ..
ln fulldir/file.txt ./
rm -rf fulldir
mkdir -p fulldir
mv file.txt fulldir/

3
मेरा जवाब वही करता है। exce [pt यह dir पर कोई अनुमति नहीं खोता है।
मोकेसर

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

1
यह निश्चित रूप से सबसे सरल उत्तर है।
बेन लियानेज

17

मेरे वैज्ञानिक लिनक्स 6 OS पर यह काम करता है:

shopt -s extglob
rm !(file.txt)

मैं भी डेबियन 32bit एक आभासी मशीन पर स्थापित किया है। ऊपर काम नहीं करता है, लेकिन निम्नलिखित करता है:

find . -type f ! -name 'file.txt' -delete

1
आपका मतलब है कि findमैंने जो समाधान दिया वह काम नहीं किया?
2

"काम नहीं किया" या "काम नहीं कर रहा है"। हां आपका खोज समाधान भी काम करता है। धन्यवाद।
कैंतुरा

1
क्या आप इसे और अधिक विवरण दे सकते हैं? कैसे "काम नहीं किया? यह अन्य फ़ाइलों को नहीं हटाता है, या इसे हटा दिया है file.txtया कुछ और?
cuonglm

मेरा मतलब था कि डेबियन ओएस पर "$ rm! (File.txt)" रिटर्न "बुरी तरह से रखा () है"। इसलिए मैंने "$ shopt -s extglob" की कोशिश की, लेकिन यह लौटा: "shopt: कमांड नहीं मिला"। फिर मैंने "खोज" समाधान की कोशिश की। यह वास्तव में कारगर है।
कांटुरा

1
ओह, तो बेशक यह काम नहीं करता है। बिलियन shoptनहीं है tcsh
cuonglm

10

के rm !("file.txt")बजाय का उपयोग करेंrm !(file.txt)


4
जो बिल्कुल कोई फर्क नहीं पड़ता है। यहाँ मुद्दा यह था कि ओपी 1 था) इस प्रारूप का समर्थन करने वाले शेल का उपयोग नहीं कर रहा है और 2) यहां तक ​​कि बैश में भी, आपको इसे सक्षम करने की आवश्यकता है shopt -s extglob। किसी भी मामले में, एक साधारण फ़ाइल नाम को उद्धृत करने से कोई फर्क नहीं पड़ता।
terdon

1
सिर्फ बर्तन फोल्डर रखने के लिए - rm -rf! ("Utils")
James Jithin

7

बस एक अलग उत्तर देने के लिए, आप डिफ़ॉल्ट व्यवहार का उपयोग कर सकते हैं rmकि यह फ़ोल्डर नहीं हटाएगा:

mkdir tmp && mv file.txt tmp  # create tmp dir and move files there
rm                            # delete all other files
mv tmp/* . && rm -rf tmp      # move all files back and delete tmp dir

1

मुझे लगता है कि यह दृष्टिकोण बहुत सरल है, काम करता है, और इसके लिए किसी विशेष एक्सटेंशन की आवश्यकता नहीं है (जो मुझे पता है!)

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