मैं कई फ़ाइल प्रकारों के लिए grep --include विकल्प का उपयोग कैसे करूं?


98

जब मैं सभी HTML फ़ाइलों को किसी निर्देशिका में grep करना चाहता हूं, तो मैं निम्नलिखित कार्य करता हूं

grep --include="*.html" pattern -R /some/path

जो अच्छा काम करता है। समस्या यह है कि कुछ निर्देशिका में सभी html, htm, php फ़ाइलों को कैसे तैयार करें?

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

grep --include="*.{html,php,htm}" pattern -R /some/path

लेकिन दुख की बात है कि यह मेरे लिए काम नहीं करेगा।
FYI करें, मेरा grep संस्करण 2.5.1 है।

जवाबों:


139

आप कई --includeझंडे का उपयोग कर सकते हैं । यह मेरे लिए काम करता है:

grep -r --include=*.html --include=*.php --include=*.htm "pattern" /some/path/

हालांकि, आप Deruijterसुझाए गए अनुसार कर सकते हैं । यह मेरे लिए काम करता है:

grep -r --include=*.{html,php,htm} "pattern" /some/path/

भूल जाते हैं कि आप उपयोग कर सकते हैं नहीं है findऔर xargsकरने के लिए बात की इस तरह के लिए:

find /some/path/ -name "*.htm*" -or -name "*.php" | xargs grep "pattern"

HTH


1
मैं समस्या देखता हूं। मैंने शेल का विस्तार करने के लिए --include = " । {Html, php}" का उपयोग किया था, जो उसी समय {html, php} का विस्तार करने के लिए शेल को रोकते हैं। ऐसा लगता है कि साइन इन --include = * शेल को '*' के विस्तार से रोकने में सक्षम है।
tianyapiaozi

xargs वास्तव में एक विकल्प नहीं है; बहुत बार जब आपको इस सुविधा की आवश्यकता होती है, तो आप xargs से अधिक फ़ाइलों से निपटेंगे।
जेम्स मूर

2
@JamesMoore: जीएनयू समानांतर पर एक नज़र डालें । यह अक्सर एक विकल्प के रूप में इस्तेमाल किया जा सकता है xargsयह भी एक त्वरित पढ़ने के लायक है। HTH।
स्टीव

3
@tianyapiaozi: आप सही हैं कि ब्रेस विस्तार के आसपास उद्धृत करना समस्या है; हालांकि, उद्धृत किए बिना, *अभी भी टोकन के हिस्से के रूप में ग्लोबिंग के अधीन है , जो इसमें अंतर्निहित है , यह सिर्फ इस मामले में कुछ भी मैच नहीं करने के लिए होता है , क्योंकि शाब्दिक रूप से केवल कुछ नाम वाली फाइलें --include=foo.htmlमेल खाती होंगी। सुरक्षित होने के लिए, *(जो आप व्यक्तिगत रूप से कर सकते हैं \*) को उद्धृत करें । एक अतिरिक्त बोनस के रूप में यह नेत्रहीन यह स्पष्ट करता है कि वह शेल नहीं है जो इस मामले में ग्लोबिंग प्रदर्शन करना चाहिए।
mklement0

2
के रूप में findसमाधान: का उपयोग कर -exec grep "pattern" {} +के बजाय | xargs grep "pattern"और अधिक मजबूत (रिक्तियों के साथ हैंडल फ़ाइल नाम, उदाहरण के लिए) के साथ-साथ और अधिक कुशल है।
mklement0

32

का प्रयोग {html,php,htm}केवल एक के रूप में काम कर सकते हैं ब्रेस विस्तार है, जो एक गैरमानक (नहीं POSIX संगत) की सुविधा है bash, kshऔर zsh

  • दूसरे शब्दों में: एक स्क्रिप्ट में इसका उपयोग करने की कोशिश न करें जो लक्ष्य /bin/sh- उस मामले में स्पष्ट कई --includeतर्कों का उपयोग करें ।

  • grepखुद को नोटेशन नहीं समझता {...}

एक ब्रेस विस्तार के लिए पहचाना जाना चाहिए , यह कमांड लाइन पर एक निर्विवाद (एक) टोकन होना चाहिए

एक ब्रेस विस्तार कई तर्कों के लिए फैलता है , इसलिए मामले में हाथ कई विकल्पों grepको देखते हुए समाप्त होता है , जैसे कि आपने उन्हें व्यक्तिगत रूप से पारित किया था। --include=...

ब्रेस विस्तार के परिणाम ग्लोबिंग (फ़ाइलनाम विस्तार) के अधीन होते हैं , जिसमें नुकसान होते हैं :

  • प्रत्येक जिसके परिणामस्वरूप तर्क आगे मिलान फ़ाइल नाम करने के लिए विस्तारित किया जा सकता है अगर यह शामिल करने के लिए होता है गैर उद्धृत जैसे ग्लोबिंग अक्षरों से परे *
    हालांकि, यह टोकन के साथ होने की संभावना नहीं है --include=*.html, जैसे (उदाहरण के लिए, आपके पास फ़ाइल का शाब्दिक नाम होना चाहिए, जैसे --include=foo.htmlकि मिलान करने के लिए कुछ ऐसा है), यह सामान्य रूप से ध्यान में रखने योग्य है।

  • यदि nullglobशेल विकल्प चालू होता है ( shopt -s nullglob) और ग्लोबिंग कुछ भी मैच नहीं करता है , तो तर्क को छोड़ दिया जाएगा ।

इसलिए, पूरी तरह से मजबूत समाधान के लिए, निम्नलिखित का उपयोग करें:

grep -R '--include=*.'{html,php,htm} pattern /some/path
  • '--include=*.'एकल-उद्धृत होने के कारण शाब्दिक माना जाता है ; यह एक ग्लोबिंग चरित्र के रूप में अनजाने व्याख्या को रोकता है ।*

  • {html,php,htm}, की - आवश्यकता का - निर्विवाद ब्रेस विस्तार [1] , 3 तर्कों का विस्तार करता है, जो {...} सीधे '...'टोकन का पालन करने के कारण , उस टोकन को शामिल करता है।

  • इसलिए, शेल द्वारा उद्धरण हटाने के बाद, निम्नलिखित 3 शाब्दिक तर्क अंततः दिए गए हैंgrep :

    • --include=*.html
    • --include=*.php
    • --include=*.htm

[१] अधिक सटीक रूप से, यह ब्रेस विस्तार के केवल वाक्यविन्यास-प्रासंगिक भाग हैं जिन्हें अयोग्य घोषित किया जाना चाहिए, सूची तत्वों को अभी भी व्यक्तिगत रूप से उद्धृत किया जा सकता है और होना चाहिए यदि उनमें ग्लोबिंग मेटाबाट्रर्स होते हैं जो ब्रेस विस्तार के बाद अवांछित ग्लोबिंग हो सकता है; इस मामले में आवश्यक नहीं है, ऊपर के रूप में लिखा जा सकता है
'--include=*.'{'html','php','htm'}


1
इस पोस्ट के लिए बहुत - बहुत धन्यवाद। महान पोस्ट न केवल प्रश्न का उत्तर देते हैं बल्कि आपको कुछ नया सिखाते हैं! यह हम में से उन लोगों के लिए विशेष रूप से उपयोगी है, जिन्हें पोसिक्स का अनुपालन करने की आवश्यकता है। मैक ओएस एक्स का उपयोग करने वाले किसी को भी यहां देखना चाहिए!
सबलाबा

@ सालाबाला: मुझे यह सुनकर खुशी हुई, लेकिन स्पष्ट होना: जबकि ब्रेस विस्तार POSIX- अनुरूप नहीं है, यह bashकिसी भी मंच पर काम करता है जो bashचलता है।
mklement0

9

दोहरे उद्धरण चिह्नों को हटाने का प्रयास करें

grep --include=*.{html,php,htm} pattern -R /some/path

@tianyapiaozi कोशिश करें grep --include=\*.{html,php,htm} pattern -R /some/path। इसने मेरे लिए काम किया।
Hyunjun Kim

4

क्या यह काम नहीं कर रहा है?

  grep pattern  /some/path/*.{html,php,htm} 

ज़रुरी नहीं। फाइलें उपनिर्देशिका के उपनिर्देशिका में निवास कर सकती हैं
tianyapiaozi

2

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

    grep "pattern" <path> -r -s -n --include=*.{c,cpp,C,h}

यह मेरे लिए विशेष रूप से सबसे अच्छा जवाब है, और मुझे लगता है कि आप -r -s -n के बजाय -nn डाल सकते हैं (लेकिन यह नाइट्रिकिंग है)।
स्लिम

आमतौर पर मैं -rns का उपयोग करता हूं । उदाहरण में स्पष्टता के लिए मुझे -r -n -s :-) खुशी है कि यह मदद की थी।
प्रदीप

मैं -Iमानक सेट में जोड़ने की सलाह देता हूं । यह बाइनरी फ़ाइलों को छोड़ देता है (जो शायद ही कभी खोजा जाता है) इसलिए दक्षता को बढ़ाता है। फिर हम जाते हैं grep -rIns ...जो ध्वनिक रूप से अच्छी तरह से बजाता है :)
खूनी

2

यह एक ही उद्देश्य के लिए काम करता है, लेकिन --includeविकल्प के बिना । यह grep 2.5.1 पर भी काम करता है।

grep -v -E ".*\.(html|htm|php)"

0

कमांड के grepसाथ प्रयोग करेंfind

find /some/path -name '*.html' -o -name '*.htm' -o -name '*.php' -type f 
 -exec grep PATTERN {} \+

आप उपयोग कर सकते हैं -regexऔर -regextypeविकल्प भी।

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