लिनक्स पर, मैं उन सभी फ़ाइलों को कैसे ढूंढ सकता हूं जिनमें एक स्ट्रिंग है और उन्हें हटा दें?


17

मैं उन सभी फ़ाइलों को हटाना चाहता हूं जिनमें स्ट्रिंग है foo। मैं लिनक्स में बैश का उपयोग कैसे कर सकता हूं?


वह स्ट्रिंग इसका फ़ाइल नाम है?
r --dʒɑ

3
स्पष्ट करें: आप हटाना फ़ाइलें जिसका करना चाहते हैं नाम शामिल हैं foo(उदाहरण के लिए myfoo.jpg), या फ़ाइलों को बाइट क्रम में होते हैं foo(जो बाइनरी फ़ाइलें जो सिर्फ इसलिए बाइट्स की है कि अनुक्रम को रोकने के लिए होने शामिल हो सकते हैं)?
हमार

जवाबों:


33

यहाँ एक सुरक्षित तरीका है:

grep -lrIZ foo . | xargs -0 rm -f --
  • -l प्रिंट पैटर्न खोज से मेल खाती फाइलों के नाम दर्ज करता है।
  • -rfooदिए गए निर्देशिका में पैटर्न के लिए एक पुनरावर्ती खोज करता है .। यदि यह काम नहीं करता है, तो प्रयास करें -R
  • -I(पूंजी i) पीडीएफ की तरह बाइनरी फ़ाइलों को छोड़ दिया जाता है।
  • -Z यह सुनिश्चित करता है कि फ़ाइल नाम शून्य हैं (यानी, nul-) को समाप्त कर दिया गया है ताकि सफेद स्थान वाले नाम की गलत तरीके से व्याख्या न हो (यानी, एक के बजाय कई नाम)।
  • xargs -0शून्य (nul) बाइट्स द्वारा शब्दों को अलग grepकरने से फ़ाइल नामों को खिलाता rm -fहै ( -Zसे विकल्प याद रखें grep)।
  • --अक्सर भूल जाता है लेकिन विकल्पों के अंत को चिह्नित करना और उन फ़ाइलों को हटाने की अनुमति देना बहुत महत्वपूर्ण है जिनके नाम के साथ शुरू होता है -

यदि आप यह देखना चाहते हैं कि कौन सी फाइलें डिलीट होने वाली हैं, तो केवल उस | xargs -0 rm -f --हिस्से को हटा दें , और Zविकल्प को छोड़ दें grep

एक अन्य उपयोगकर्ता ने निम्नलिखित की तरह कुछ सुझाया, जिसे आपको असुरक्षित नहीं होना चाहिए :

files=`grep foo * | cut -d: -f1`
rm -f $files         # unsafe, do not run it!

अगर मेरे पास ऐसी फाइलें हैं, ImportantStuffजिन्हें मैं हटाना नहीं चाहता और obsolete ImportantStuffशामिल करना चाहता fooहूं, तो मैं इस कमांड को चलाने के दौरान ImportantStuff(और नहीं obsolete ImportantStuff !) खो देता हूं, क्योंकि $filesइसकी व्याख्या होने पर रिक्त स्थान टूट जाता है। इस तरह से स्केलर शेल चर में फ़ाइलनाम की सूची डालना खतरनाक है।


17
$ find -type f -exec grep -q "foo" {} \; -exec echo rm -- {} \;

यह पुनरावर्ती फ़ाइलों वाली फ़ाइलों को खोजता है foo। दूसरा -execकेवल तभी चलाया जाता है जब पहला execसफलतापूर्वक बाहर निकलता है, अर्थात यदि grepमिलान करता है। ड्राईरुन और निकालें echoयदि आउटपुट सही लगता है।

या वैकल्पिक रूप से

$ find -type f -exec grep -q "foo" {} \; -print

तथा

$ find -type f -exec grep -q "foo" {} \; -delete

जैसा कि लेकेनस्टाइन ने सुझाव दिया था।


4
... जिसे छोटा किया जा सकता है: find -type f -exec grep -q 'foo' {} \; -delete(आसपास के उद्धरण {}बेमानी हैं, findफाइलों को हटाने में भी सक्षम है।)। ध्यान दें कि grepएक नियमित अभिव्यक्ति को स्वीकार करता है। यदि आप खोज करना चाहते हैं foo.bar, तो या तो बच जाएं या -Fपैटर्न को शाब्दिक रूप से मानने का विकल्प पास करें ।
लेकेनस्टेयॉन

उपयोग करने का कोई कारण -exec echo rm "{}" \;और नहीं -delete?
vartec

1
@vartec नहीं, मैं उपयोग करूँगा -delete-execजगह में दूसरी और गूंज के साथ प्रदर्शित करना आसान है।
एड्रियन फ्रुविर्थ

1
टाइप करना आसान है -print(या -lsअधिक वाचालता के लिए) -exec echo rm "{}" \'। बाहरी उपयोगिताओं के लिए कोई ज़रूरत नहीं है।
लेकेनस्टीएन

1
यदि आप rm {} का उपयोग करते हैं, तो rm - {} का उपयोग करें, ताकि फ़ाइल नाम में कोई भी विशेष वर्ण स्वयं प्रक्षेपित न हों। उदाहरण के लिए, स्पर्श '-rf /' किसी भी निर्देशिका आप लिखने की अनुमति है, जहां में ...
ATK

1

मैं वही करूंगा जो एड्रियन कहता है,

लेकिन मैं शब्द सीमा को जोड़ने के लिए foo में arond जोड़ सकता हूं ताकि "भोजन" वाली फ़ाइलों को आकस्मिक रूप से न हटाएं (जब तक कि यह भोजन युक्त सब कुछ नहीं हटा रहा है जो आप चाहते हैं।)

 $ find -type f -exec grep -q "\<foo\>" {} \; -delete

अकस्मात, मैं हटाने से पहले आउटपुट पुनर्निर्देशित करूंगा ताकि मैं हटाने से पहले समीक्षा कर सकूं:

 $ find -type f -exec grep -q "\<foo\>" > /tmp/list_of_files_to_delete

जैसे ही आप टिप्पणी पोस्ट करने में सक्षम होते हैं, आपको टिप्पणी जैसी चीजों को पोस्ट करना चाहिए।
FSMaxB

हाँ, मैंने पहले कोशिश की लेकिन फिर महसूस किया कि मुझे अभी तक टिप्पणी पोस्ट करने की अनुमति नहीं है।
पेट्टर एच।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.