सवाल "ढूंढें" का उपयोग करके कुछ फ़ाइल नामों को अनदेखा कैसे करें?


मेरे पसंदीदा बाश आदेशों में से एक है:

find . -name '*.*' -exec grep 'SearchString' {} /dev/null \;

जो निर्दिष्ट खोज स्ट्रिंग के लिए वर्तमान निर्देशिका के नीचे और नीचे सभी फ़ाइलों की सामग्री की खोज करता है। एक डेवलपर के रूप में, यह कई बार काम में आ गया है।

मेरे वर्तमान प्रोजेक्ट के कारण, और मेरे कोडबेस की संरचना के बावजूद, मैं इस बीएसएचएच कमांड को ".svn", या किसी भी फाइल वाली निर्देशिका में या नीचे किसी भी फाइल को खोजकर और भी उन्नत नहीं करना चाहता हूं ".html" के साथ समाप्त

हालांकि मुझे मैन्युअल रूप से भ्रमित करने के लिए मैन पेज। मैंने -प्रून का उपयोग करने की कोशिश की, और यह मुझे अजीब व्यवहार दिया। केवल .html पृष्ठों को छोड़ने के प्रयास में (शुरू करने के लिए), मैंने कोशिश की:

find . -wholename './*.html' -prune -exec grep 'SearchString' {} /dev/null \;

और उस व्यवहार को नहीं मिला जिसे मैं उम्मीद कर रहा था। मुझे लगता है कि मैं -प्रमुख बिंदु खो सकता हूं। क्या आप लोग मेरी मदद कर सकते हैं?

धन्यवाद


112
2018-03-05 23:28


मूल


सिर्फ आपकी जानकारी के लिए: find बिल्ड-इन बैश कमांड नहीं है बल्कि एक अलग प्रोग्राम है - WakiMiko
आप फाइल के अंदर फाइल खोज सकते हैं grep -rl 'SearchString' - emanuele
@emanuele हाय, SuperUser (और स्टैक एक्सचेंज नेटवर्क) में आपका स्वागत है। यह एक प्रश्न है जिसे मैंने पूछा, और इसका उत्तर दिया गया, 2 1/2 साल पहले। आम तौर पर, यदि आप प्रश्न का उत्तर जोड़ना चाहते हैं, तो कृपया टिप्पणी के बजाए नीचे स्क्रॉल करके और वहां जवाब देकर ऐसा करें। चूंकि इस प्रश्न में पहले से ही एक स्वीकृत उत्तर है (हरे रंग की चेकमार्क वाला एक), यह संभावना नहीं है कि आपका उत्तर अधिक ध्यान देने जा रहा है। FYI करें। - Cody S
हाय, यह आपके प्रश्न का उत्तर नहीं है। यह केवल एक टिप है, जैसा कि आपने उपयोग किए जाने वाले प्रस्ताव में कहा था find एक फ़ाइल के अंदर खोजने के लिए। - emanuele
Fwiw, -name '*.*' नहीं मिला सब फाइलें: केवल उन्हीं के साथ . उनके नाम पर (का उपयोग *.* आमतौर पर एक डॉस-आईएसएम है, जबकि यूनिक्स में, आप आमतौर पर केवल उपयोग करते हैं * उसके लिए)। वास्तव में उन सभी से मेल खाने के लिए, पूरी तरह से तर्क को हटा दें: find . -exec ...। या यदि आप केवल फ़ाइलों को grep लागू करना चाहते हैं (और निर्देशिका छोड़ें) तो करें find . -type f -exec ...। - Stefan


जवाब:


आप विशिष्ट नामों वाली फ़ाइलों से मेल नहीं खाते खोजने के लिए नकारात्मक (!) सुविधा का उपयोग कर सकते हैं:

find . ! -name '*.html' ! -path '*.svn*' -exec grep 'SearchString' {} /dev/null \;

तो यदि नाम .html में समाप्त होता है या पथ में कहीं भी .svn होता है, तो यह मेल नहीं खाएगा, और इसलिए निष्पादन निष्पादित नहीं किया जाएगा।


159
2018-03-06 00:40



क्या मुझे अभी भी निर्दिष्ट करना चाहिए- नाम '।'कहीं कहीं? क्या मैं इससे पहले, या अस्वीकृति के बाद ऐसा करूंगा? - Cody S
तुम्हारा इरादा था *.* यह सुनिश्चित करने के लिए मैच करें कि इसमें केवल मिलान वाली फाइलें हों .? एक की अनुपस्थिति में सभी फाइलों का मिलान होगा name निर्देश, तो उपरोक्त HTML और svn को छोड़कर सब कुछ मिल जाएगा - Paul
मुझे लगता है कि आप चाहते हैं -wholename '*.svn*' बजाय -name। - fuenfundachtzig
हाँ, यह करता है, ताकि .svn निर्देशिका खोज परिणामों से बाहर रखा गया है। - fuenfundachtzig
@Noumenon ! -name '.' बाहर करना चाहिए . खोज परिणामों से। - Paul


मेरे पास लंबे समय तक एक ही समस्या है, और कई समाधान हैं जो विभिन्न परिस्थितियों में लागू हो सकते हैं:

  • ack-grep एक प्रकार का "डेवलपर है grep" कौन कौन से डिफ़ॉल्ट रूप से संस्करण नियंत्रण निर्देशिका और अस्थायी फ़ाइलों को छोड़ देता है। man पृष्ठ बताता है कि केवल विशिष्ट फ़ाइल प्रकारों को कैसे खोजा जाए और कैसे करें अपना खुद का परिभाषित करें
  • grepस्वयं का --exclude तथा --exclude-dir विकल्पों को छोड़ने के लिए विकल्प बहुत आसानी से इस्तेमाल किया जा सकता है globs तथा एक निर्देशिका (दुर्भाग्य से निर्देशिकाओं के लिए कोई globbing)।
  • find . \( -type d -name '.svn' -o -type f -name '*.html' \) -prune -o -print0 | xargs -0 grep ... काम करना चाहिए, लेकिन उपरोक्त विकल्प शायद लंबे समय तक परेशानी से कम हैं।

9
2018-03-06 13:54





निम्नलिखित find कमांड निर्देशिकाओं का नाम है शामिल  .svn, हालांकि यह निर्देशिका में नहीं उतरता है, प्रयुक्त पथ का नाम मुद्रित किया जाता है ... (-name '*.svn' कारण है!) ..

आप निर्देशिका नामों को फ़िल्टर कर सकते हैं: grep -d skip जो चुपचाप ऐसे इनपुट "निर्देशिका नाम" छोड़ देता है।

जीएनयू grep के साथ, आप उपयोग कर सकते हैं -H के बजाय /dev/null। मामूली पक्ष के मुद्दे के रूप में: \+ से बहुत तेज हो सकता है \;उदाहरण के लिए। उपयोग कर 1 मिलियन वन लाइन फाइलों के लिए \; इसमें 4m20s, का उपयोग कर \+ यह केवल लिया 1.2s

निम्नलिखित विधि का उपयोग करता है xargs के बजाय -exec, और मानते हैं कि कोई नई लाइनें नहीं हैं \n आपकी किसी भी फाइल में नाम। जैसा कि यहां प्रयोग किया जाता है, xargs खोज के समान ही है \+

xargs फ़ाइल-नाम पास कर सकते हैं जिसमें इनपुट डिलीमीटर को बदलकर लगातार रिक्त स्थान होते हैं '\n' उसके साथ -d विकल्प।

इसमें निर्देशिकाएं हैं जिनके नाम शामिल  .svn और केवल उन फ़ाइलों को पकड़ता है जो समाप्त नहीं होते हैं .html

find . \( -name '*.svn*' -prune  -o ! -name '*.html' \) |
   xargs -d '\n' grep -Hd skip 'SearchString'

7
2018-03-06 03:29



इंगित करने के लिए धन्यवाद \+ -exec कार्रवाई का संस्करण। मामूली पक्ष के मुद्दों के लिए हुरेय! - Christian Long
बेशक, के बाद से + खोल के लिए एक विशेष चरित्र नहीं है, आपको टाइप करने की आवश्यकता नहीं है \ इससे पहले। - Scott