टीएल; डीआर: सबसे अच्छा तरीका है -exec rm
इसके बजाय उपयोग करना है -delete
।
find a \( -name b -prune \) -o -type f -exec rm {} +
स्पष्टीकरण:
क्यों मिल रहा है शिकायत है जब आप इस्तेमाल करने की कोशिश -delete
के साथ -prune
?
संक्षिप्त उत्तर: क्योंकि -delete
तात्पर्य है -depth
और अप्रभावी -depth
बनाता है -prune
।
इससे पहले कि हम लंबे उत्तर पर आएं, पहले और साथ में पाए जाने वाले व्यवहार को देखें -depth
:
$ find foo/
foo/
foo/f1
foo/bar
foo/bar/b2
foo/bar/b1
foo/f2
एकल निर्देशिका में आदेश के बारे में कोई गारंटी नहीं है। लेकिन इस बात की गारंटी है कि किसी निर्देशिका को उसकी सामग्री से पहले संसाधित किया जाता है। नोट foo/
किसी भी पहले foo/*
और foo/bar
किसी भी पहले foo/bar/*
।
इससे उलटा हो सकता है -depth
।
$ find foo/ -depth
foo/f2
foo/bar/b2
foo/bar/b1
foo/bar
foo/f1
foo/
ध्यान दें कि अब सभी foo/*
पहले दिखाई देते हैं foo/
। उसी के साथ foo/bar
।
दीर्घ उत्तर:
-prune
एक निर्देशिका में उतरने से रोकता है। दूसरे शब्दों -prune
में निर्देशिका की सामग्री को छोड़ देता है। आपके मामले -name b -prune
में नाम के साथ किसी भी निर्देशिका में उतरने से रोकता है b
।
-depth
निर्देशिका से पहले ही किसी निर्देशिका की सामग्री को संसाधित करने के लिए खोज करता है। इसका मतलब यह है कि जब तक निर्देशिका की प्रविष्टि की प्रक्रिया शुरू नहीं हो जाती, तब तक b
इसकी सामग्री पहले ही संसाधित हो चुकी होती है। इस प्रकार प्रभाव -prune
से अप्रभावी -depth
है।
-delete
तात्पर्य है -depth
कि यह फ़ाइलों को पहले और फिर खाली निर्देशिका को हटा सकता है। -delete
गैर-रिक्त निर्देशिका को हटाने से इंकार करना। मुझे लगता है कि -delete
गैर-खाली निर्देशिकाओं को हटाने और / या रोकने के -delete
लिए मजबूर करने के लिए एक विकल्प जोड़ना संभव होगा -depth
। लेकिन वो दूसरी कहानी है।
आप जो चाहते हैं उसे प्राप्त करने का एक और तरीका है:
find a -not -path "*/b*" -type f -delete
यह याद रखना आसान हो भी सकता है और नहीं भी।
यह कमांड अभी भी डायरेक्टरी में उतरता है b
और इसमें हर एक फाइल को केवल उन्हीं के -not
लिए अस्वीकार करता है। यदि निर्देशिका b
बड़ी है , तो यह एक प्रदर्शन समस्या हो सकती है।
-path
से अलग काम करता है -name
। संपूर्ण पथ के विरुद्ध मिलान -name
करते समय केवल नाम (फ़ाइल या निर्देशिका के) -path
से मेल खाता है। उदाहरण के लिए पथ का निरीक्षण करें /home/lesmana/foo/bar
। -name -bar
मिलान कर देंगे क्योंकि नाम है bar
। -path "*/foo*"
मिलान होगा क्योंकि स्ट्रिंग /foo
पथ में है। -path
कुछ पेचीदगियों का उपयोग करने से पहले आपको समझना चाहिए। find
अधिक विवरण के लिए मैन पेज पढ़ें ।
खबरदार कि यह 100% मूर्ख नहीं है। "झूठी सकारात्मक" की संभावना है। जिस तरह से कमांड ऊपर लिखा गया है वह किसी भी फ़ाइल को छोड़ देगा जिसमें कोई भी मूल निर्देशिका है जिसका नाम b
(सकारात्मक) के साथ शुरू हो रहा है । लेकिन यह किसी भी फ़ाइल को छोड़ देगा जो नाम b
पेड़ में स्थिति की परवाह किए बिना (झूठी सकारात्मक) के साथ शुरू हो रहा है। इससे बेहतर अभिव्यक्ति लिखकर इसे ठीक किया जा सकता है "*/b*"
। इसे पाठक के लिए एक अभ्यास के रूप में छोड़ दिया जाता है।
मुझे लगता है कि आपने उपयोग किया a
और b
प्लेसहोल्डर के रूप में और असली नाम अधिक पसंद हैं allosaurus
और brachiosaurus
। यदि आप उसकी brachiosaurus
जगह रखते हैं b
तो झूठी सकारात्मकता की मात्रा में भारी कमी आएगी।
कम से कम झूठी सकारात्मकता को हटाया नहीं जाएगा , इसलिए यह उतना दुखद नहीं होगा। इसके अलावा, आप पहले बिना कमांड चलाकर झूठी सकारात्मकता की जांच कर सकते हैं -delete
(लेकिन निहित को याद रखना -depth
) और आउटपुट की जांच करना।
find a -not -path "*/b*" -type f -depth
a
छोड़कर कैसे शामिल करते हैंa/b
?