Grep --exclude का उपयोग करें / - कुछ फ़ाइलों के माध्यम से grep नहीं करने के लिए सिंटैक्स शामिल करें


779

मैं foo=एक निर्देशिका ट्री में पाठ फ़ाइलों में स्ट्रिंग की तलाश कर रहा हूं । यह एक आम लिनक्स मशीन पर है, मेरे पास बैश शेल है:

grep -ircl "foo=" *

निर्देशिका में कई बाइनरी फाइलें भी होती हैं जो "foo =" से मेल खाती हैं। जैसा कि ये परिणाम प्रासंगिक नहीं हैं और खोज को धीमा कर रहे हैं, मैं चाहता हूं कि इन फ़ाइलों (ज्यादातर JPEG और PNG छवियों) की खोज को छोड़ें। मुझे यह कैसे करना है?

मुझे पता है कि विकल्प --exclude=PATTERNऔर --include=PATTERNविकल्प हैं, लेकिन पैटर्न प्रारूप क्या है? Grep का मैन पेज कहता है:

--include=PATTERN     Recurse in directories only searching file matching PATTERN.
--exclude=PATTERN     Recurse in directories skip file matching PATTERN.

Grep पर खोज करना शामिल है , grep में शामिल नहीं है , grep को बाहर करना और भिन्न को प्रासंगिक कुछ भी नहीं मिला

यदि केवल कुछ फ़ाइलों में बेहतर तरीके से तैयारी है, तो मैं इसके लिए हूँ; आपत्तिजनक फाइलों को स्थानांतरित करना एक विकल्प नहीं है। मैं केवल कुछ निर्देशिकाओं को नहीं खोज सकता (निर्देशिका संरचना एक बड़ी गड़बड़ी है, हर जगह सब कुछ के साथ)। इसके अलावा, मैं कुछ भी स्थापित नहीं कर सकता, इसलिए मुझे सामान्य उपकरणों (जैसे grep या सुझाई गई खोज ) के साथ करना होगा।


13
सिर्फ FYI करें, उपयोग किए गए तर्क: -c फाइल -i केस-
इनसेंसिटिव

68
Svn dirs को बाहर करने का एक तेज़ तरीका है --exclude-dir=.svn, इसलिए grep उन सब में नहीं जाता है
orip

25
लोगों को जानने की आवश्यकता हो सकती है: 1. यहाँ ग्लोब के आसपास उद्धरणों की कमी पर ध्यान दें: --excee = ' । {png, jpg}' काम नहीं करता (कम से कम मेरे GNU grep संस्करण के साथ) क्योंकि grep अपने ग्लब्स में {} का समर्थन नहीं करता है। इसके बाद के संस्करण को '--exclude = .png --exclude = *। Jpg' में विस्तारित किया गया है । grep को ठीक-ठाक पसंद है। 2. --exclude एक GNU एक्सटेंशन है और POSIX की परिभाषा grep का हिस्सा नहीं है, इसलिए यदि आप स्क्रिप्ट का उपयोग करते हुए लिखते हैं तो यह जान लें कि वे गैर-GNU सिस्टम पर नहीं चलेंगे।
आईजी

2
अपवर्जित उपयोग का पूरा उदाहरण:grep -r --exclude-dir=var "pattern" .
Tisch

जवाबों:


766

शेल ग्लोबिंग सिंटैक्स का उपयोग करें:

grep pattern -r --include=\*.{cpp,h} rootdir

के लिए वाक्यविन्यास --excludeसमान है।

ध्यान दें कि शेल द्वारा विस्तारित होने से रोकने के लिए स्टार को पीछे छोड़ दिया जाता है (इसे उद्धृत करते हुए, जैसे कि --include="*.{cpp,h}", यह भी काम करेगा)। अन्यथा, यदि आपके पास वर्तमान कार्यशील निर्देशिका में कोई फ़ाइल है जो पैटर्न से मेल खाती है, तो कमांड लाइन कुछ इस तरह विस्तारित होगी grep pattern -r --include=foo.cpp --include=bar.h rootdir, जो केवल नाम की फ़ाइलों को खोजेगी foo.cppऔर bar.h, जो कि संभवत: वह नहीं है जो आप चाहते थे।


8
मुझे पता नहीं क्यों, लेकिन मुझे इस तरह शामिल पैटर्न को कोट करना था:grep pattern -r --include="*.{cpp,h}" rootdir
टॉपेक

6
@topek: अच्छा बिंदु - यदि आपके पास अपनी वर्तमान निर्देशिका में कोई .cpp / .h फाइलें हैं, तो शेल, grep को लागू करने से पहले शेल का विस्तार करेगा, इसलिए आप एक कमांड लाइन की तरह समाप्त करेंगे grep pattern -r --include=foo.cpp --include=bar.h rootdir, जो केवल फाइलों को खोजेगी नाम दिया foo.cppया bar.h। यदि आपके पास वर्तमान निर्देशिका में ग्लोब से मेल खाने वाली कोई फ़ाइल नहीं है, तो शेल ग्लोब पर grep से गुजरता है, जो इसे सही ढंग से व्याख्या करता है।
एडम रोसेनफील्ड

6
मुझे बस एहसास हुआ कि ग्लोब का उपयोग केवल फाइलनाम से मेल खाने के लिए किया जाता है। एक पूरी निर्देशिका को बाहर करने के लिए एक --exclude-dirविकल्प की जरूरत है। हालांकि समान नियम लागू होते हैं। केवल निर्देशिका फ़ाइल नाम का मिलान किया जाता है, पथ का नहीं।
Krzysztof Jabłoński

3
--includeके बाद काम करने के लिए प्रतीत नहीं होता है --exclude। मुझे लगता है कि यह भी कोशिश करने के लिए कोई मतलब नहीं है, सिवाय इसके कि मुझे aliasएक लंबी सूची के साथ grep करना है --excludeऔर --exclude-dir, जिसका उपयोग मैं खोज कोड के लिए उपयोग करता हूं, पुस्तकालयों और स्वैप फ़ाइलों और चीजों को अनदेखा करता हूं। मुझे उम्मीद थी कि grep -r --exclude='*.foo' --include='*.bar'यह काम करेगा, इसलिए मैं केवल अपने aliasतक --include='*.bar'ही सीमित रह सकता हूं , लेकिन ऐसा लगता है --includeकि इसमें सब कुछ शामिल है और यह सब कुछ शामिल है जो एक .foo फ़ाइल नहीं है। के आदेश --includeऔर --excludeकाम स्वैपिंग, लेकिन अफसोस, यह मेरे साथ मददगार नहीं है alias
माइकल शीपर

1
इसके लिए नियम बनाने के लिए हम किसी के दिमाग को कैसे पढ़ सकते हैं PATTERN। आधे घंटे का मुझे कोई भी विवरण नहीं मिल सकता है कि वे वहाँ क्या कर रहे हैं
अर्कादि

221

यदि आप केवल बाइनरी फ़ाइलों को छोड़ना चाहते हैं, तो मेरा सुझाव है कि आप -I(ऊपरी मामले में) विकल्प देखें। यह बाइनरी फ़ाइलों को अनदेखा करता है। मैं नियमित रूप से निम्नलिखित कमांड का उपयोग करता हूं:

grep -rI --exclude-dir="\.svn" "pattern" *

यह पुनरावर्ती खोज करता है, बाइनरी फ़ाइलों को अनदेखा करता है, और जो भी पैटर्न मैं चाहता हूं उसके लिए सबवर्सन छिपे हुए फ़ोल्डर के अंदर नहीं दिखता है। मैंने इसे काम पर अपने बॉक्स पर "ग्रेप्सवन" के रूप में उतारा है।


1
धन्यवाद, यह मेरे द्वारा सामना किए गए कुछ अन्य परिदृश्यों के लिए बहुत उपयोगी है।
पिस्कोर ने

25
--exclude-dirहर जगह उपलब्ध नहीं है। GNU grep 2.5.1 के साथ मेरे आरएच बॉक्स में काम नहीं है।
gcb

--exclude-dirअनुपलब्ध होने पर क्या उपयोग करना है, इसके लिए कोई सुझाव ? मेरे सभी अटेम्प्स में, --excludeबिल फिट करने के लिए प्रकट नहीं होता है।
JMTyler

आप हमेशा GNU से नवीनतम grep स्रोत डाउनलोड कर सकते हैं, और 'कॉन्फ़िगर' कर सकते हैं; बनाना; सुडो मेक इनस्टॉल ’। यह पहली चीजों में से एक है जो मैं मैक या पुराने लिनुक्स वितरण पर करता हूं।
जोनाथन हार्टले

3
बिल्कुल वही जो मुझे चाहिए था। दरअसल, मैं गिट का उपयोग करता हूं। तो, --exclude-dir="\.git"। :-)
आयनिक बिज़ू

66

कृपया एक नजर डालिए , जो बिल्कुल इन स्थितियों के लिए बनाई गई है। आपका उदाहरण है

grep -ircl --exclude=*.{png,jpg} "foo=" *

इस ack के साथ किया जाता है

ack -icl "foo="

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

ack -icl --cpp "foo="

अच्छा लग रहा है, अगली बार स्टैंडअलोन पर्ल संस्करण की कोशिश करेंगे, धन्यवाद।
पिस्कोर ने

5
अच्छी कॉल, मैं अब बिना चोंच के नहीं रह सकता।
संभावना

1
stackoverflow.com/questions/667471/… - यह आपको विंडोज़ पर एकेक प्राप्त करने की अनुमति देगा, अगर वह वह जगह है जहाँ से आप grep चला रहे हैं।
TamusJRoyce

हो सकता है कि आप चाहते हैं @Chance silversearcher-एजी , बस apt-getउबंटू में :)
Justme0

के साथ भ्रमित नहीं होनाawk
jasonleonhard

35

grep 2.5.3 ने --exclude-dir पैरामीटर पेश किया जो आपके इच्छित तरीके से काम करेगा।

grep -rI --exclude-dir=\.svn PATTERN .

आप एक पर्यावरण चर भी सेट कर सकते हैं: GREP_OPTIONS = "- बहिष्कृत dir =। Svn"

मैं ack के लिए दूसरे एंडी का वोट लूंगा , हालांकि यह सबसे अच्छा है।


7
सटीक संस्करण संख्या का उल्लेख करने के लिए +1; मेरे पास grep 2.5.1 है और बाहर करने का dir विकल्प उपलब्ध नहीं है
James

25

मैंने इसे लंबे समय के बाद पाया, आप इसमें कई शामिल कर सकते हैं और शामिल कर सकते हैं:

grep "z-index" . --include=*.js --exclude=*js/lib/* --exclude=*.min.js

5
उन्हें एक सूची में संयोजित करना बेहतर है जैसे: --exclude = {pattern1, pattern2, pattern3}
यासर सिनजाब

12

सुझाया गया आदेश:

grep -Ir --exclude="*\.svn*" "pattern" *

वैचारिक रूप से गलत है, क्योंकि --exclude बेसन पर काम करता है। दूसरे शब्दों में कहें, तो यह वर्तमान निर्देशिका में केवल .svn को छोड़ देगा।


3
हाँ, यह मेरे लिए बिल्कुल काम नहीं करता है। जो मेरे लिए काम करता था, वह था: बहिष्कार-डीर =। एसवीएन
टरिन ईस्ट

2
@ निकोला धन्यवाद! मैं अपने बालों को फाड़ रहा हूँ, यह काम क्यों नहीं करेगा। मुझे बताएं, क्या मैनपेज से इसे खोजने का कोई तरीका है? सभी कहते हैं कि यह "पैटर्न" से मेल खाता है। EDIT मैनपेज कहता है "फ़ाइल", जैसा कि यहां बताया गया है fixunix.com/unix/…
13ren

11

Grep 2.5.1 में आपको इस लाइन को ~ / .bashrc या ~ / .bash प्रोफाइल में जोड़ना होगा

export GREP_OPTIONS="--exclude=\*.svn\*"

9

मुझे लगता है कि क्रेपिंग grep का आउटपुट कभी-कभी बहुत सहायक होता है:

grep -rn "foo=" . | grep -v "Binary file"

हालाँकि, यह वास्तव में इसे बाइनरी फ़ाइलों को खोजने से नहीं रोकता है।


10
आप grep -Iबाइनरी फ़ाइलों को छोड़ने के लिए उपयोग कर सकते हैं ।
नाथन फेलमैन

यह भी किया है कि जब मैं छोटा था ... अब मुझे बेहतर पता है और जब एक समस्या का सामना करना पड़ता है, तो पहली बात
आरटीएफएम है

ग्रेपिंग ग्रेप रंग हाइलाइट्स को हटा देगा।
मैक्स ली

7

यदि आप उपयोग करने के लिए प्रतिकूल नहीं हैं find, तो मुझे इसकी -pruneविशेषता पसंद है :

find [directory] \
        -name "pattern_to_exclude" -prune \
     -o -name "another_pattern_to_exclude" -prune \
     -o -name "pattern_to_INCLUDE" -print0 \
| xargs -0 -I FILENAME grep -IR "pattern" FILENAME

पहली पंक्ति में, आप वह निर्देशिका निर्दिष्ट करते हैं जिसे आप खोजना चाहते हैं। .(करंट डायरेक्टरी) एक मान्य पथ है, उदाहरण के लिए।

2 और 3 लाइनों, उपयोग पर "*.png", "*.gif", "*.jpg", और इसके आगे। इनमें से कई का उपयोग करें-o -name "..." -prune निर्माणों कि आपके पास पैटर्न हैं।

4 वीं पंक्ति पर, आपको एक और चाहिए -o(यह निर्दिष्ट करता है "या" से find), जिस पैटर्न को आप चाहते हैं, और आपको इसके अंत में -printया तो इसकी आवश्यकता -print0है। तुम सिर्फ चाहते हैं "सब कुछ" है कि अवशेष pruning के बाद *.gif, *.pngआदि छवियों, तो का उपयोग -o -print0और आप 4 लाइन के साथ काम हो गया।

अंत में, 5 वीं पंक्ति पर पाइप है, xargsजो उन परिणामस्वरूप फ़ाइलों में से प्रत्येक को लेता है और उन्हें एक चर में संग्रहीत करता है FILENAME। इसके बाद यह झंडे से गुजरता grepहै , और फिर इसके द्वारा विस्तारित फ़ाइलनाम की सूची बन जाती है-IR"pattern"FILENAMExargsfind

आपके विशेष प्रश्न के लिए, कथन कुछ इस तरह दिखाई दे सकता है:

find . \
     -name "*.png" -prune \
     -o -name "*.gif" -prune \
     -o -name "*.svn" -prune \
     -o -print0 | xargs -0 -I FILES grep -IR "foo=" FILES


एक संशोधन मैं सुझाता हूं: -falseप्रत्येक -pruneका उपयोग करने के लिए भूल जाने के तुरंत बाद शामिल करें -print0या किसी प्रकार की execकमांड वास्तव में उन फ़ाइलों को प्रिंट नहीं करेगी जिन्हें आप बाहर करना चाहते थे: -name "*.png" -prune -false -o name "*.gif -prune -false...
OnlineCop

7

CentOS 6.6 / Grep 2.6.3 पर, मुझे इसे इस तरह उपयोग करना होगा:

grep "term" -Hnir --include \*.php --exclude-dir "*excluded_dir*"

समान चिन्हों की कमी पर ध्यान दें "=" (अन्यथा --include,--exclude , include-dirऔर --exclude-dirअनदेखी कर रहे हैं)


6

git grep

उपयोग करें git grepजो प्रदर्शन के लिए अनुकूलित है और कुछ फ़ाइलों के माध्यम से खोज करना है।

डिफ़ॉल्ट रूप से यह बाइनरी फाइलों को नजरअंदाज करता है और यह आपके सम्मान में है .gitignore। यदि आप गिट संरचना के साथ काम नहीं कर रहे हैं, तो आप अभी भी इसे पारित करके उपयोग कर सकते हैं --no-index

उदाहरण वाक्य रचना:

git grep --no-index "some_pattern"

अधिक उदाहरणों के लिए, देखें:


5

मैं एक dilettante हूँ, दी गई, लेकिन यहाँ मेरा ~ / .bash_profile दिखता है:

निर्यात GREP_OPTIONS = "- orl --exclude-dir = .svn --exclude-dir =। cache --color = auto" GREP_COLOR = '1; 32';

ध्यान दें कि दो निर्देशिकाओं को बाहर करने के लिए, मुझे दो बार --exclude-dir का उपयोग करना पड़ा।


3

इसको आजमाओ:

$ मिल गया। -name "* .txt" -type f -print | xargs फ़ाइल | grep "फू =" | cut -d: -f1

यहाँ स्थापित: http://www.unix.com/shell-programming-scripting/42573-search-files-excluding-binary-files.html


3
यह रिक्त स्थान के साथ फ़ाइल नाम पर काम नहीं करता है, लेकिन प्रिंट के बजाय प्रिंट0 का उपयोग करके और xargs के लिए -0 विकल्प जोड़कर उस समस्या को आसानी से हल किया जाता है।
एडम रोसेनफील्ड

3

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

grep "foo" *.{html,txt}

html और txt शामिल हैं। यह केवल वर्तमान निर्देशिका में खोज करता है।

उपनिर्देशिकाओं में खोज करने के लिए:

   grep "foo" */*.{html,txt}

उप-सीमाएँ में:

   grep "foo" */*/*.{html,txt}

3

निर्देशिकाओं में कई बाइनरी फाइलें भी हैं। मैं केवल कुछ निर्देशिकाओं को नहीं खोज सकता (निर्देशिका संरचना एक बड़ी गड़बड़ है)। वहाँ केवल कुछ फ़ाइलों में grepping का एक बेहतर तरीका है?

ripgrep

यह आपकी वर्तमान निर्देशिका को पुन: खोज करने के लिए डिज़ाइन किए गए सबसे तेज़ टूल में से एक है। यह Rust में लिखा गया है , जो अधिकतम दक्षता के लिए Rust के regex इंजन के ऊपर बनाया गया है । चेक यहाँ विस्तृत विश्लेषण

तो आप बस चला सकते हैं:

rg "some_pattern"

यह आपका सम्मान करता है .gitignoreऔर स्वचालित रूप से छिपी हुई फाइलों / निर्देशिकाओं और बाइनरी फाइलों को छोड़ देता है।

आप अभी भी -g/ का उपयोग करके फ़ाइलों और निर्देशिकाओं को शामिल या अनुकूलित कर सकते हैं --glob। ग्लोबिंग नियम ग्लब्स से मेल खाते हैं .gitignoreman rgमदद के लिए जाँच करें ।

अधिक उदाहरणों के लिए, देखें: कुछ फ़ाइलों को grep के साथ कुछ एक्सटेंशन से मेल नहीं खाने के लिए कैसे अलग करें?

MacOS पर, आप के माध्यम से स्थापित कर सकते हैं brew install ripgrep


3

ढूँढें और xargs आपके मित्र हैं। उन्हें grep --exclude के बजाय फ़ाइल सूची को फ़िल्टर करने के लिए उपयोग करें

कुछ ऐसा आजमाएं

find . -not -name '*.png' -o -type f -print | xargs grep -icl "foo="

इसका उपयोग करने का लाभ यह है कि यह अन्य उपयोग के मामलों के लिए विस्तार योग्य है, उदाहरण के लिए सभी गैर-पीएनजी छवियों में लाइनों की गणना करने के लिए:

find . -not -name '*.png' -o -type f -print | xargs wc -l

सभी गैर-png फ़ाइलों को निकालने के लिए:

find . -not -name '*.png' -o -type f -print | xargs rm

आदि।

जैसा कि टिप्पणियों में बताया गया है, अगर कुछ फाइलों में उनके नाम, उपयोग -print0और xargs -0इसके बजाय रिक्त स्थान हो सकते हैं ।


1
यह रिक्त स्थान के साथ फ़ाइल नाम पर काम नहीं करता है, लेकिन प्रिंट के बजाय प्रिंट0 का उपयोग करके और xargs के लिए -0 विकल्प जोड़कर उस समस्या को आसानी से हल किया जाता है।
एडम रोसेनफील्ड

2

उन स्क्रिप्ट सभी समस्या को पूरा नहीं करते हैं ... इस बेहतर प्रयास करें:

du -ha | grep -i -o "\./.*" | grep -v "\.svn\|another_file\|another_folder" | xargs grep -i -n "$1"

यह स्क्रिप्ट इतनी बेहतर है, क्योंकि यह निर्देशिका से निर्देशिकाओं से बचने के लिए "वास्तविक" नियमित अभिव्यक्तियों का उपयोग करती है। "\" के साथ केवल अलग फ़ोल्डर या फ़ाइल नाम grep -v पर

इसका आनंद लें! मेरे linux खोल पर पाया! एक्सडी


2

@ यह देखो।

grep --exclude="*\.svn*" -rn "foo=" * | grep -v Binary | grep -v tags

2
लगभग इसे प्राप्त करने वाली चीजें अन्य पदों में शामिल की गई हैं; क्या अधिक है, यह गलत है, जिसमें विभिन्न लेआउट विकल्पों के साथ यह पंक्ति संख्या और चीजों को गड़बड़ करेगा या संदर्भ की पंक्तियों को बाहर कर देगा जो वांछित था।
क्रिस मॉर्गन

आप एक ही समय में कई "-v" विकल्पों का उपयोग कैसे कर सकते हैं?
रास्ता खोलें

1

--binary-files=without-matchजीएनयू का विकल्प grepइसे बाइनरी फ़ाइलों को छोड़ने के लिए मिलता है। ( -Iकहीं और उल्लिखित स्विच के बराबर ।)

(इसके लिए हाल के संस्करण की आवश्यकता हो सकती है grep; 2.5.3 में यह कम से कम है।)


1

tcsh .alias फ़ाइल के लिए उपयुक्त:

alias gisrc 'grep -I -r -i --exclude="*\.svn*" --include="*\."{mm,m,h,cc,c} \!* *'

मुझे यह पता लगाने में थोड़ा समय लगा कि {mm, m, h, cc, c} भाग उद्धरणों के अंदर नहीं होना चाहिए। ~ कीथ


0

Grep से सभी बाइनरी परिणामों को अनदेखा करने के लिए

grep -Ri "pattern" * | awk '{if($1 != "Binary") print $0}'

Awk हिस्सा सभी बाइनरी फ़ाइल फू मैच लाइनों को फ़िल्टर करेगा


-2

इसे इस्तेमाल करे:

  1. एक फ़ोल्डर बनाएं जिसका नाम " --Fदही के नीचे है .." (या दूसरे फ़ोल्डर का नाम बदलकर " --F" नाम दिया गया है) double-minus-F
  2. #> grep -i --exclude-dir="\-\-F" "pattern" *
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.