Unix - PATTERN को छोड़कर फ़ाइलों और फ़ोल्डरों को हटा दें


10

हाल ही में मुझे एक विशिष्ट पैटर्न से मेल खाते वाले निर्देशिका को छोड़कर सभी फ़ाइलों / फ़ोल्डरों को हटाने के कार्य का सामना करना पड़ा। इसलिए मैंने काम करने के लिए सिंगल-लाइन यूनिक्स कमांड को पकाया। क्या यह केवल एक पंक्ति होनी चाहिए? मुझे नहीं लगता, लेकिन यह निश्चित रूप से उस तरह से ठंडा है!

जबकि समस्या बहुत सरल है, मैं थोड़ा हैरान था कि मेरा समाधान कितना जटिल था। यहां मैंने जो कमांड इस्तेमाल किया है; नोट: यह एक खराब समाधान है क्योंकि यह फ़ाइल-नाम वाले वर्ण-वर्णों को नहीं संभालता है (जो मेरी स्थिति में कोई फर्क नहीं पड़ता)।

ls | grep -v PATTERN | xargs -n1 -IREPLACE rm -rf REPLACE

मैंने "खोज" कमांड का उपयोग नहीं किया क्योंकि मैं PATTERN से मेल खाने वाले फ़ोल्डरों में पुनरावृत्ति नहीं करना चाहता। उदाहरण के लिए, निम्नलिखित फ़ाइल संरचना पर विचार करें:

file_foo.txt
first_dir
  |
  +--> contents
  +--> ...
foo_dir
  |
  +--> anotherfile.txt
  +--> morefiles.log
foo_file.txt
somefile.txt

पैटर्न "foo" का उपयोग केवल "first_dir" (और यह निश्चित रूप से सामग्री) और "somefile.txt" (निकालना होगा नहीं "anotherfile.txt" या "morefiles.log")।

प्रश्न, क्या इसे पूरा करने के बेहतर (अधिक सुरुचिपूर्ण और सही) तरीके हैं?


संपादित करें:
यह हाल ही में मेरे ध्यान में लाया गया था कि "खोज" एक बेहतर विकल्प हो सकता है :

find * -maxdepth 0 ! -name PATTERN -print0 | xargs -0n1 rm -rf

यह समाधान लाइन-फीड वर्ण वाले पथ को सही ढंग से संभालता है।


संपादित करें: "first_dir" को सही करने के लिए गलत "the_dir" बदला गया।
joxl

जवाबों:


10

निम्नलिखित उदाहरणों ने echoउपसर्ग किया है ताकि आप वास्तव में उनका उपयोग करने से पहले पैटर्न का परीक्षण कर सकें। echoको सक्रिय करने के लिए निकालें rm -rfrm -riपुष्टि के लिए संकेत करने के लिए स्थानापन्न ।

ksh के पास अपने ग्लोबिंग के लिए एक नकारात्मक मैच एक्सटेंशन है:

# ksh
echo rm -rf !(*foo*)

यदि आप विकल्प सेट करते हैं तो वही सिंटैक्स बैश में उपलब्ध है extglob:

# bash
shopt -s extglob
echo rm -rf !(*foo*)

इसके लिए zsh का अपना सिंटैक्स है:

# zsh
setopt extended_glob
echo rm -rf ^*foo*

यह ksh -style सिंटैक्स का भी उपयोग कर सकता है :

# zsh: ksh-style glob syntax
setopt ksh_glob no_bare_glob_qual
echo rm -rf !(*foo*)

# zsh: ksh-style glob syntax, adapted for the default bare_glob_qual option
setopt ksh_glob bare_glob_qual
echo rm -rf (!(*foo*))

सरल, सुरुचिपूर्ण, हैंडल लाइनफीड अक्षर, (लगभग) एक पंक्ति (मैं जोड़ दिया है shopt -s extglobमेरी .bashrc फाइल करने के लिए, तो यह अब है एक एक लाइनर)। उत्तम! जैसे ही मेरी प्रतिष्ठा इसकी अनुमति देती है मैं एक वादा करता हूं।
joxl

7

यहाँ एक और findउपाय है। मुझे यकीन नहीं है कि यह आपके ऊपर कोई वास्तविक लाभ है, लेकिन इसकी आवश्यकता नहीं है xargsऔर इस दुर्लभ संभावना के लिए अनुमति देता है कि * बहुत अधिक नामों तक फैलता है।

find . -maxdepth 1 ! -name PATTERN -type f -delete

मैंने यह भी जोड़ा -type fताकि यह निर्देशिकाओं को हटाने का प्रयास न करे।

चेतावनी: -deleteशक्तिशाली है। मैंने अपनी एक परीक्षण फ़ाइल 0 अनुमतियाँ दी और ऊपर की कमांड ने बिना किसी हिचकिचाहट के इसे हटा दिया।


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

ध्यान से पढ़ें, टिप्पणी है कि मैं कर निकालें निर्देशिका के लिए इच्छा। और find -deleteगैर-खाली निर्देशिकाओं को नहीं हटाएगा। यह भी देखें कि find -maxdepth 1मैच " (वर्तमान निर्देशिका) जो वास्तव में खराब है। यद्यपि मुझे आपके विचार को समाप्त करने की इच्छा है xargs, लेकिन कोई find -execवैकल्पिक रूप से उपयोग कर सकता है । find * -maxdepth 0 ! -name PATTERN -exec rm -rf '{}' \;
जॉक्स २ j

0

आप इस रॉल लिपि उदाहरण का उपयोग कर सकते हैं http://askcodegeneration.com/keep-subversion/ इसके बजाय जो बहुत अधिक समझ में आता है और जो उपयोगकर्ता चयन जैसे फ़ोल्डर चयन और पुष्टि का प्रबंधन कर सकता है:

delete-file: func[file][
    if/else none? find file "/.svn/" [
        delete file
    ][
        print ["keeping" file]
    ]
]
dir: request-dir
ans: ask rejoin ["Do you confirm " dir "? (Yes): "]
if (ans = "Yes") [
    foreach-file dir :delete-file
]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.