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


143

मेरा पसंदीदा BASH कमांड है:

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

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

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

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

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

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

धन्यवाद


1
जस्ट find
फी: बिल्ट

1
आप के अंदर फ़ाइल खोज सकते हैंgrep -rl 'SearchString'
इमानुएल

@emanuele नमस्ते, सुपरयूज़र (और स्टैक एक्सचेंज नेटवर्क) में आपका स्वागत है। यह एक प्रश्न है जो मैंने पूछा था, और इसका उत्तर दिया था, 2 1/2 साल पहले। आमतौर पर, यदि आप प्रश्न का उत्तर जोड़ना चाहते हैं, तो कृपया नीचे की ओर स्क्रॉल करें और टिप्पणी के बजाय, वहां उत्तर दें। चूँकि इस प्रश्न का पहले से ही स्वीकृत उत्तर है (हरे चेकमार्क वाला), इसलिए यह संभावना नहीं है कि आपके उत्तर पर अधिक ध्यान दिया जाएगा। FYI करें।
कोडी एस

1
नमस्ते, यह आपके प्रश्न का उत्तर नहीं है। यह केवल एक टिप है, जैसा कि आपने प्रस्तावना में कहा है कि findकिसी फ़ाइल के अंदर खोजने के लिए उपयोग करें।
इमानुएल

2
एफडब्ल्यूआईडब्ल्यू, सभी फाइलों -name '*.*'को नहीं ढूंढता है : केवल उनके नाम वाले लोग (का उपयोग आमतौर पर एक डॉस-आईएसएम है, जबकि यूनिक्स में, आप आमतौर पर सिर्फ उसी के लिए उपयोग करते हैं)। वास्तव में उन सभी से मेल खाने के लिए, बस तर्क को पूरी तरह से हटा दें :। या यदि आप केवल फाइलों के लिए grep लागू करना चाहते हैं (और निर्देशिकाओं को छोड़ें) तो करें । .*.**find . -exec ...find . -type f -exec ...
स्टेफेन

जवाबों:


197

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

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

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


1
क्या मुझे अभी भी निर्दिष्ट करना चाहिए -नाम ' 'वहाँ कहीं? क्या मैं इससे पहले या नकारने के बाद ऐसा करूंगा?
कोड़ी एस

क्या आपके *.*मैच का इरादा केवल यह सुनिश्चित करना था कि इसमें फ़ाइलों का मिलान हो .? फाइंड एक nameनिर्देश के अभाव में सभी फाइलों से मेल खाएगा , इसलिए ऊपर html और svn को छोड़कर सब कुछ मेल खाएगा
पॉल

5
मुझे लगता है कि आप के -wholename '*.svn*'बजाय चाहते हैं -name
फेनफुन्दाचट्ज़िग

2
हां, यह करता है, ताकि .svnनिर्देशिकाओं को खोज परिणामों से बाहर रखा जाए।
फेनफंडाचटजिग

1
@ नौमेनन ! -name '.'को .खोज परिणामों से बाहर करना चाहिए ।
पॉल

11

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

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

9

निम्न findआदेश उन निर्देशिकाओं को चुभता है जिनके नाम सम्‍मिलित हैं .svn , हालांकि यह निर्देशिका में नहीं उतरता है, छद्म पथ नाम मुद्रित है ... ( -name '*.svn'कारण है!)!

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

GNU ग्रिप के साथ, आप -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'

1
\+-Exec कार्रवाई के संस्करण को इंगित करने के लिए धन्यवाद । मामूली पक्ष के मुद्दों के लिए हुर्रे!
क्रिश्चियन लॉन्ग

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