पुनरावर्ती grep: विशिष्ट निर्देशिकाओं को बाहर करें


49

मैं विशिष्ट सामग्री के साथ स्रोत फ़ाइलों को खोजने के लिए पुनरावर्ती grep का उपयोग करता हूं।

grep -Rni "myfunc" .

बड़े कोडबेस पर, यह धीमा हो सकता है, इसलिए मैं प्रतिबंधित / श्वेतसूची एक्सटेंशन का उपयोग करता हूं।

grep -Rni --include=*.java "myfunc" .

हालाँकि, यह (उपने) पूरे उपनिर्देशिका को बाहर करने के लिए अधिक कुशल होगा, मैं सोच रहा हूँ:

grep -Rni --exclude=/.svn/ "myfunc" .

लेकिन --exclude केवल * .java जैसे फ़ाइल पैटर्न का समर्थन करता है। मैं निर्देशिकाओं को कैसे छोड़ सकता हूं?

जवाबों:


10

आप ack में देख सकते हैं ।

मैंने अभी इसका उपयोग शुरू किया है लेकिन यह इसके लिए अच्छी तरह से अनुकूल है।


ack बहुत अच्छा लग रहा है। अच्छा है कि यह सहज रूप से अवांछित फ़ाइलों को बाहर करता है। --nogroup विकल्प के लिए एक समान उत्पादन -Rni grep के लिए देता है
गेबर

2
Ack थोड़ा धीमा है। आप द सिल्वर सर्चर (एजी) या रिपग्रेप (आरजी) की कोशिश कर सकते हैं।
14:

62
grep -r --exclude-dir=dev --exclude-dir=sys --exclude-dir=proc PATTERN data

स्रोत: https://stackoverflow.com/questions/2799246/grep-excluding-a-specific-folder-use


17
ध्यान दें कि यह पुनरावर्ती को शामिल नहीं करता है। ./devके साथ बाहर रखा जाएगा ./foo/bar/dev--exclude-dir=./devकेवल पहले मामले पर लागू करने के लिए उपयोग करें ।
कॉरी वॉकर

4
ग्लोबिंग द्वारा आप इसे थोड़ा छोटा कर सकते हैं: ग्लोबिंग bash grep -r --exclude-dir={dev,sys,proc} PATTERN data की एकमात्र समस्या यह है कि मैं इसे अपने बैश में काम नहीं कर सकता। उस स्थिति में मुझे उन्हें अलग रखना होगा।
b01

3
यह भी कहा कि {} केवल तभी काम करता है जब आप 1 से अधिक प्रविष्टियाँ डालते हैं, इसका मतलब है --exclude-dir = {home, .svn} कार्य करता है लेकिन --exclude-dir = {। Svn} काम नहीं करेगा। यह जानने के लिए मेरा समय बर्बाद होता है कि {} काम नहीं करता क्योंकि मैं पहली बार 1 प्रविष्टि के साथ परीक्षण करता हूं।
林果 林果

यदि आप {}एक एकल प्रविष्टि के साथ उपयोग करते हैं, तो आपको संभवतः इसे एक सरणी बनाने के लिए एक संयुक्त अल्पविराम की आवश्यकता होती है (यह सुनिश्चित नहीं है कि बैश कैसे संभालता है)। यह करने के बजाय कि मैंने अपने .bash_aliases में एक उपनाम बनाना शुरू कर दिया है, जो उन फ़ोल्डरों की सूची में रहता है जिन्हें मैं आमतौर पर बाहर करना चाहता हूं, जैसे .it, .svn, .hg, .cache, और फिर मैं उन्हें एक लूप के माध्यम से जोड़ता हूं। --exclude-dir $dirऔर फिर उस सरणी को grep उपनाम में विस्तारित करें।
ड्रैगन 788

6

आप इसके बजाय पा सकते हैं:

find . -not -path "*/.svn*" -not -type d -exec grep -ni "myfunc" {} \; -print

ठीक है, इसलिए यह थोड़ा पीछे की ओर है, तो आपको पहले और फिर पथ के grep परिणाम मिलते हैं । शायद किसी और का बेहतर जवाब है?


3
ठीक है, मुझे वह बहुत पसंद है। बेशक मिल बहुत अधिक लचीला है। आउटपुट के बीच एकमात्र अंतर यह है कि "grep -Rni" प्रत्येक मैच के लिए फ़ाइल नाम को प्रिंट करेगा, जबकि "फाइंड -सेक्स grep" एक लाइन पर फ़ाइल नाम प्रिंट करेगा और फिर प्रत्येक मैच के लिए एक लाइन (लाइन नंबर और लाइन सामग्री के साथ) )। "grep -Hni" का उपयोग करके फ़ाइल नाम को प्रत्येक पंक्ति पर प्रदर्शित करने के लिए मजबूर करता है
gabab

केवल वही उत्तर प्रदान करने के लिए धन्यवाद, जो सिस्टम के लिए काम करता है, जो इस crusty हैं, बिना grep --exclude-dir, लेकिन फिर भी काम किया जाएगा
दमित्री DB

2

यहां मेरी एक परियोजना में एक स्क्रिप्ट से एक पूर्ण उदाहरण है जो मदद कर सकता है, मैं इस फ़ाइल को "all_source" (निष्पादन योग्य के रूप में चिह्नित) कहता हूं और इसे मेरी परियोजना के रूट डायर में डाल देता हूं, फिर इसे grep myfunc $(./all_source)स्क्रिप्ट के अंत में छंटनी की तरह कहता हूं वैकल्पिक।

#!/bin/bash

find . \
    -type d \( \
            -wholename './lib' -o \
            -wholename './vc6' -o \
            -name 'gen' -o \
            -name '.svn' \
            \) -prune -o \
    -type f \( \
            -name '*.h' -o \
            -name '*.cpp' -o \
            -name '*.c' -o \
            -name '*.lua' -o \
            -name '*.*awk' \) -print \
    | sort

यह स्क्रिप्ट मेल खाने वाले प्रोजेक्ट के सभी फ़ाइल नामों को लौटाती है *.h, *.cpp, *.c, *.lua, *.*awk, लेकिन .svn और जीन फ़ोल्डरों के नाम वाले सभी फ़ोल्डरों में खोज नहीं करती है और साथ ही ( ./libऔर ./vc6प्रोजेक्ट रूट के केवल राइट्स) फोल्डर को छोड़ देती है । तो जब आप ऐसा करते हैं grep myfunc $(./all_source)तो केवल उन फाइलों में। आपको इसे प्रोजेक्ट के रूट डायर से भी कॉल करना होगा।


0

खोजने के लिए -prune विकल्प भी है:

 find . -path "*/.svn*" -prune -o -not -type d -exec grep -ni "myfunc" {} \; -print

0

आप ऐसा करने की कोशिश कर सकते हैं:

grep -R  "myfunc" . | grep -v path_to_exclude/

उदाहरण: यदि आप लॉग फ़ाइलों में सामग्री को खोजना नहीं चाहते हैं तो बस निम्नलिखित कार्य करें:

grep -R "myfunc" . | grep -v log/
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.