टीएल; डीआर: सबसे अच्छा तरीका है -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?