उपनिर्देशिका सहित पाठ खोजने के लिए "grep" कमांड का उपयोग कैसे करें


373

मैं उन सभी फ़ाइलों को खोजना चाहता हूं जिनमें पाठ का एक विशिष्ट स्ट्रिंग है। grepआदेश से काम करता है, लेकिन मैं कैसे हर निर्देशिका के लिए इसका इस्तेमाल करने के (मैं इसे अपने वर्तमान निर्देशिका के लिए ही कर सकते हैं) पता नहीं है। मैंने पढ़ने की कोशिश की man grep, लेकिन इससे कोई मदद नहीं मिली।


grep -RIn <yor pattern> * सभी पाठ फ़ाइलों में वर्तमान निर्देशिकाओं से खोज करेगा। यकीन नहीं है कि * *

1
--include="*.C"विकल्प के साथ वाइल्डकार्ड , @ user311346, @Lekensteyn को धन्यवाद।
बॉब स्टीन

वर्तमान और सभी उप निर्देशिकाओं में स्ट्रिंग के लिए पुनः खोज फ़ाइलों के लिए खोज और grep संयोजन का उपयोग करें। इस Wilddiary.com/find-files-contain-my-text
Drona

जवाबों:


487

इसका इस्तेमाल करना बेहतर होगा

grep -rl "string" /path

कहाँ पे

  • -r(या --recursive) विकल्प का उपयोग किया जाता है /path, जबकि सभी उप-निर्देशिकाओं को पार करने के लिए
  • -l(या --files-with-matches) विकल्प का उपयोग केवल मिलान वाली फ़ाइलों के प्रिंटनेम के लिए किया जाता है, न कि मिलान लाइनों (यह भी गति में सुधार कर सकता है, यह देखते हुए कि grepइस विकल्प के साथ पहले मैच में एक फ़ाइल को पढ़ना बंद करें)।

13
वास्तव में अगर "स्ट्रिंग" एक टेक्स्ट पैटर्न है, तो उस कार्यक्षमता का उपयोग करना बेहतर होता है, अन्यथा किसी को समस्या का सामना करना पड़ सकता है जब स्ट्रिंग में डॉट या विशेष चरित्र होता है जिसका अर्थ है नियमित अभिव्यक्ति और न कि केवल एक डॉट जिसे स्ट्रिंग के रूप में पाया जाना चाहिए। , जैसा है। तब मैं -rlFस्विच का उपयोग करता हूं , -F"निश्चित स्ट्रिंग" के लिए (और उदाहरण के लिए regexp - नहीं)। बेशक, यदि कार्य regexps का उपयोग कर रहा था, तो मुझे क्षमा करें। निश्चित रूप से, बिना -r के भी यही सिद्धांत है, मैं अक्सर देखता हूं कि लोग grep खोजों को "पाठ" मानते हैं और यह उन समस्याओं का कारण बन सकता है जो विशेष रूप से एक रेगीक्स के रूप में कुछ का मतलब है।
एलजीबी

4
-iझंडा भी है जो मामले की अनदेखी करता है।
मार्को Ceppi

3
मैं केवल --recursiveविकल्प दिखाने के लिए , वहाँ विकल्प और उपयोग परिदृश्यों के टन के बारे में बात कर सकते हैं। मैंने @dmityugov से शुरू किए गए उत्तर को स्वीकार किया और बिना काम करने के लिए संशोधित किया find
enzotib

1
@NN: किया गया :-)
enzotib

3
@ScottBiggs: विकल्प के साथ--include '*.h'
enzotib

167

यदि आप फ़ाइलों में मेल खाने वाली लाइनों की तलाश कर रहे हैं, तो मेरा पसंदीदा कमांड है:

grep -Hrn 'search term' path/to/files
  • -H फ़ाइल नाम मुद्रित होने का कारण बनता है (एकाधिक फ़ाइलों को खोजे जाने पर निहित)
  • -r एक पुनरावर्ती खोज करता है
  • -n लाइन नंबर प्रिंट करने का कारण बनता है

path/to/files.वर्तमान निर्देशिका में खोज करने के लिए हो सकता है

आगे के विकल्प जो मुझे बहुत उपयोगी लगे:

  • -Iबाइनरी फ़ाइलों को अनदेखा करें (पूरक: -aसभी फ़ाइलों को पाठ के रूप में देखें)
  • -Fsearch termएक शाब्दिक के रूप में व्यवहार करें , एक नियमित अभिव्यक्ति नहीं
  • -i केस-असंवेदनशील खोज करें
  • --color=alwaysजब पाइपिंग के माध्यम से भी रंगों को मजबूर करना lesslessसमर्थन रंग बनाने के लिए, आपको -rविकल्प का उपयोग करने की आवश्यकता है :

    grep -Hrn search . | less -r
    
  • --exclude-dir=dirकी तरह निर्देशिकाओं को छोड़कर के लिए उपयोगी .svnऔर .git

उदाहरण आउटपुट


13
-Hएक फ़ोल्डर में बेमानी है, अगर वहाँ अधिक है तो एक फ़ाइल, जैसा कि संभावित है। वास्तव में, मैन पेज कहता है-H, --with-filename: Print the file name for each match. This is the default when there is more than one file to search.
enzotib

मुझे नहीं पता था कि, यह हमेशा वैसा ही काम करता था जैसा मुझे उम्मीद थी। फ़ाइलों की तलाश करते समय यह मेरी डिफ़ॉल्ट कमांड है।
लेकेन्स्टाइन

1
वहाँ केवल एक के साथ फ़ाइलों पर विचार करने के लिए एक रास्ता है, कहते हैं, .a extention (और इस -r के साथ गठबंधन करने के लिए)?
2224 बजे user2413

6
@ user2413 कोशिश करें--include '*.*'
Lekensteyn

1
@alper कोशिशgrep --exclude='*~' ...
Lekensteyn

24

मेरा मानना ​​है कि आप इस तरह से कुछ का उपयोग कर सकते हैं:

find /path -type f -exec grep -l "string" {} \;

टिप्पणियों से स्पष्टीकरण

findएक कमांड है जो आपको फाइलों और अन्य ऑब्जेक्ट्स जैसे निर्देशिकाओं और लिंक को दिए गए पथ के उपनिर्देशिकाओं में ढूंढने देता है। यदि आप एक मास्क निर्दिष्ट नहीं करते हैं जो फ़ाइलनाम को मिलना चाहिए, तो यह सभी निर्देशिका ऑब्जेक्ट्स को एन्यूमरेट करता है।

  • -type f निर्दिष्ट करता है कि इसे केवल फ़ाइलों को संसाधित करना चाहिए, निर्देशिकाओं को नहीं आदि।
  • -exec grepनिर्दिष्ट करता है कि हर मिली फ़ाइल के लिए, उसे grep कमांड को चलाना चाहिए, फ़ाइल नाम के साथ उसके तर्क के रूप में, {}फ़ाइल नाम के साथ प्रतिस्थापित करके

3
बस उन लोगों के लिए जो नहीं जानते हैं, -name '*.py'मैच को '.py' में समाप्त होने वाली फ़ाइलों के लिए प्रतिबंधित करता है।
डैनियल एफ

मुझे यह पसंद है कि यह ऐसे क्लाइंट को कवर करता है जिनके पास -R उनके grep कमांड में लागू नहीं होता है।
Aviose

यदि आप मैचिंग लाइन और फ़ाइल नाम प्रिंट करना चाहते हैं, तो जैसे निष्पादन करें:... -exec bash -c 'grep -r "mystring" {} && echo {}' \;
डोन ली

बस सीधे grep का उपयोग करने के लिए सापेक्ष क्या है?
जोनाथन

19

मेरी डिफ़ॉल्ट कमांड है

grep -Rin string *

मैं एक कैपिटल 'आर' lsका उपयोग करता हूं क्योंकि इसका उपयोग पुनरावर्ती के लिए करता है। चूंकि grep दोनों को स्वीकार करता है, इसलिए इसका उपयोग नहीं करने का कोई कारण नहीं है।

संपादित करें: एचवीएनएस ट्विटिंग के अनुसार, जाहिरा तौर पर सिमिलिंक -Rका पालन करेंगे जहां -rनहीं होगा।


1
छिपी हुई फ़ाइलों में भी खोज करने के लिए, चलाएं shopt -s dotglob( -s"सेट" के रूप में याद रखें )। फ़ाइलों को निकालते समय सावधान रहें। यदि आपने डॉटग्लोब को सक्षम किया है, rm -r *तो वर्तमान डायर में सब कुछ हटा देता है, लेकिन इसके अलावा निर्देशिका भी क्योंकि ..मैच। डॉटग्लोब को अक्षम करने के लिए, shopt -u dotglob(" परेशान ") का उपयोग करें । परिवर्तन अस्थायी हैं, यह केवल वर्तमान शेल पर लागू होता है।
लेकेन्स्टाइन

मैं इस बारे में भूल गया। वहाँ एक एक लाइन के लिए इसे स्थापित करने का एक तरीका है? कुछ shopt -s dotglob & <grep cmd> & shopt -y dotglobऔर ही सुविधाजनक है? इस तरह से हमें इसे रीसेट करने की चिंता नहीं करनी होगी
user606723

इसके अलावा, grep -Rin string .इन मामलों में से अधिकांश का उपयोग करना आसान है । मैं सिर्फ * का उपयोग करता हूं क्योंकि यह अधिक स्वाभाविक रूप से आता है।
user606723

1
यदि आप पुनरावर्ती grep करते हैं, तो आप बस "से शुरू कर सकते हैं।" के बजाय "*"। कोई डॉटग्लोब की जरूरत नहीं।
मिशैल errajer

1
इस पर ध्यान दें, एक चीज का उल्लेख मैनपेज में नहीं है R, प्रतीकात्मक लिंक का अनुसरण करेगा, rनहीं
HVNSweeting

12

यदि आप कुछ नया करने की कोशिश करने को तैयार हैं, तो ackएक शॉट दें। इसके लिए वर्तमान निर्देशिका को पुन: खोज करने का आदेश stringहै:

ack string

स्थापना काफी सरल है:

curl http://betterthangrep.com/ack-standalone > ~/bin/ack && chmod 0755 !#:3

(बशर्ते आपको पहले से ही निर्देशिका मिल गई हो ~/binऔर यह आपके में अधिमानतः हो PATH।)


2
या सिर्फ apt-grep स्थापित करें, (और अपने .bashrc में alias ack =
are

chmodकमांड के अंतिम पैरामीटर क्या करते हैं? क्या वे विशिष्ट हैं chmodया वे संबंधित ( !#:3हिस्सा) बैश हैं ?
इलियट डारिंक

@ElliottDarfink यह बैश के इतिहास फीचर का उपयोग कर रहा है - !एक ईवेंट डिज़ाइनर है । वे पुनरावृत्ति से बचने के लिए बहुत शक्तिशाली हैं। इस मामले में !#:3अब तक कमांड लाइन के तीसरे टोकन का संदर्भ है ~/bin/ack
कोनराड रुडोल्फ

4

कमांड rgrep ऐसी आवश्यकता के लिए समर्पित है

यदि उपलब्ध नहीं है, तो आप इसे इस तरह से प्राप्त कर सकते हैं

mkdir -p ~/bin
cd ~/bin
wget http://sdjf.esmartdesign.com/files/rgrep
chmod +x rgrep

जैसा कि ऊपर बताया गया है आप सीधे अपने डिफ़ॉल्ट grep विकल्पों में सेट कर सकते हैं।

मैं व्यक्तित्व का उपयोग करता हूं

[[  ${#args} -lt 5 && "${args//[[:space:]]/}" == "-i" ]] && args="-Hin"
args="${args:--Hns} --color=auto"

संबंधित विषय: हमेशा रंग के साथ rgrep का उपयोग कैसे करें


rgrep को grep पैकेज द्वारा प्रदान किया जाता है जो कि Ubuntu में डिफ़ॉल्ट रूप से स्थापित होता है।
करेल

2

अपडेट 2:

आदेशों की यह पंक्ति का उपयोग कर findऔर grepसमस्या ठीक हो जाती:

$ find path_to_search_in -type f -exec grep -in searchString {} 2> /dev/null +

--color=<always or auto> रंगीन उत्पादन के लिए:

$ find path_to_search_in -type f \
            -exec grep --color=always -in searchString {} 2>/dev/null +

उदाहरण:

$ find /tmp/test/ -type f -exec grep --color=auto -in "Search string" {} 2>/dev/null +

नीचे दिए गए स्नैपशॉट में एक उदाहरण चलता है: snap1


अपडेट 1:

आप निम्नलिखित कोड की कोशिश कर सकते हैं; अपने .bashrcया .bash_aliasesएक स्क्रिप्ट में एक समारोह के रूप में:

wherein () 
{ 
    for i in $(find "$1" -type f 2> /dev/null);
    do
        if grep --color=auto -i "$2" "$i" 2> /dev/null; then
            echo -e "\033[0;32mFound in: $i \033[0m\n";
        fi;
    done
}

उपयोग: wherein /path/to/search/in/ searchkeyword

उदाहरण:

$ wherein ~/Documents/ "hello world"

(नोट: जैसा कि @enzotib द्वारा नीचे टिप्पणियों में सुझाया गया है, यह फ़ाइल / निर्देशिकाओं के साथ उनके नामों में रिक्त स्थान सहित काम नहीं करता है)


मूल पोस्ट

स्ट्रिंग और आउटपुट को खोजने के लिए खोज स्ट्रिंग के साथ बस उस लाइन को आउटपुट करें:

$ for i in $(find /path/of/target/directory -type f); do \
    grep -i "the string to look for" "$i"; done

उदाहरण के लिए:

$ for i in $(find /usr/share/applications -type f); \
    do grep -i "web browser" "$i"; done

खोज स्ट्रिंग वाले फ़ाइलनाम को प्रदर्शित करने के लिए:

$ for i in $(find /path/of/target/directory -type f); do \
    if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;

उदाहरण के लिए:

$ for i in $(find /usr/share/applications -type f); \
    do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \
    fi; done;

रिक्त स्थान वाले फ़ाइल नाम पर विफल रहता है। असफलता को इस तथ्य से छिपाया जाता है कि स्टेडर को नहीं दिखाया गया है।
enzotib

@enzotib कि बाहर इशारा करने के लिए धन्यवाद .. यह अभी भी निर्दिष्ट फ़ंक्शन के लिए अनसुलझा है .. मैंने एक और एक लाइनर जोड़ा है ..
सटीक

अब उत्तर @dmityugov के समान है।
enzotib

हां, लेकिन इस अर्थ में इस पृष्ठ के अधिकांश उत्तर यदि आप चेक करते हैं grep, तो वे उसी तरह के हैं, जैसे कि वे उपयोग करते हैं , इसके findसाथ ही उपसमूह का भी उपयोग किया जा रहा है grep... लेकिन यदि आप अलग-अलग स्विच स्वीकार करते हैं और एक विशिष्ट उत्तर के रूप में ट्विक करते हैं, तो शायद मेरा यहाँ भी फिट होगा .. या आप अलग हैं? अंतिम अपडेट वह करता है जो मैं अपनी खोज में करना चाहता हूं: खोज कुंजी और पंक्ति संख्या के साथ लाइनों के साथ फ़ाइल नाम। भी :) और बेहतर पठनीयता के लिए रंगीन आउटपुट और त्रुटि फ़िल्टर ..
सटीक

2

grep( GNU या BSD )

आप पैरामीटर के grepसाथ पुनरावर्ती वर्तमान फ़ोल्डर को खोजने के लिए टूल का उपयोग कर सकते हैं -r, जैसे:

grep -r "pattern" .

नोट: -r- पुन : खोज उपनिर्देशिका।

विशिष्ट फ़ाइलों के भीतर खोजने के लिए, आप एक ग्लोबिंग सिंटैक्स का उपयोग कर सकते हैं जैसे:

grep "class foo" **/*.c

नोट: ग्लोबिंग विकल्प ( **) का उपयोग करके , यह विशिष्ट एक्सटेंशन या पैटर्न के साथ सभी फ़ाइलों को पुन: स्कैन करता है। इस सिंटैक्स को सक्षम करने के लिए, चलाएँ shopt -s globstar:। आप **/*.*सभी फ़ाइलों (छिपी और बिना एक्सटेंशन के) या किसी अन्य पैटर्न को छोड़कर भी उपयोग कर सकते हैं ।

यदि आपकी त्रुटि है कि आपका तर्क बहुत लंबा है, तो अपनी खोज को कम करने पर विचार करें, या findइसके बजाय सिंटैक्स का उपयोग करें :

find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'

वैकल्पिक रूप से उपयोग करें ripgrep

ripgrep

यदि आप बड़ी परियोजनाओं या बड़ी फ़ाइलों पर काम कर रहे हैं, तो आपको ripgrepइसके बजाय उपयोग करना चाहिए , जैसे:

rg "pattern" .

GitHub प्रोजेक्ट पेज पर डॉक्स, इंस्टॉलेशन स्टेप्स या सोर्स कोड चेक करें ।

ऐसा लगता है कि किसी भी अन्य उपकरण की तुलना में काफी तेज है जीएनयू / बीएसडी grep , ucg, ag, sift, ack, ptया इसी तरह की है, क्योंकि यह के शीर्ष पर बनाया गया है जंग के regex इंजन जो परिमित ऑटोमेटा, SIMD और आक्रामक शाब्दिक अनुकूलन बहुत तेजी से खोज करने के लिए उपयोग करता है।

यह .gitignoreफ़ाइलों में निर्दिष्ट पैटर्न को अनदेखा करने का समर्थन करता है , इसलिए एक एकल फ़ाइल पथ को एक साथ कई ग्लोब पैटर्न के खिलाफ मिलान किया जा सकता है।


आप आम मापदंडों का उपयोग कर सकते हैं जैसे:

  • -i - असंवेदनशील खोज।
  • -I - बाइनरी फ़ाइलों को अनदेखा करें।
  • -w - पूरे शब्दों के लिए खोजें (आंशिक शब्द मिलान के विपरीत)।
  • -n - अपने मैच की लाइन दिखाएं।
  • -C/ --context(जैसे -C5) - संदर्भ बढ़ता है, इसलिए आप आसपास के कोड को देखते हैं।
  • --color=auto - मिलान पाठ को चिह्नित करें।
  • -H - जहाँ फ़ाइल मिलती है फ़ाइल नाम प्रदर्शित करता है।
  • -c- मिलान लाइनों की संख्या प्रदर्शित करता है। के साथ जोड़ा जा सकता है -H

1

मैं xargs का उपयोग करके ऐसा करता हूं, एक बहुत ही कम आदेश दिया गया है

find ./ -type f -print0 | xargs -0 grep 'string_you_are_looking_for'

एक वर्तमान फ़ोल्डर में सभी फ़ाइलों की एक पुनरावर्ती सूची देता है। आप इसे xargs कि उन फ़ाइलों में से हर एक पर grep कमांड निष्पादित करता है।


4
विकल्प और विकल्प के xargsबिना उपयोग करने के लिए पदावनत किया जाता है, यह रिक्त स्थान वाले फ़ाइल नाम पर विफल हो जाएगा। -print0find-0xargs
enzotib

@enzotib मैंने आपके द्वारा सुझाए गए उत्तर को संपादित कर दिया है। कृपया समीक्षा करें और यदि संपादन और सुधार की आवश्यकता है, तो मैं आपके साथ फिर से संपादन करके खुश होऊंगा। धन्यवाद
αғsнιη

1
@ कासिया: यह अब ठीक है, मेरे डाउनवोट को हटा दिया।
एनज़ोटिब

0

मुझे पता है कि यहां बहुत सारे उत्तर हैं, लेकिन यहां एक विकल्प है यदि आप फ़ाइलों को खोजते समय अन्य प्रतिबंध जोड़ना चाहते हैं:

find . -type f -exec grep --quiet string_to_look_for {} ';' -print

यह काम करता है क्योंकि grepअगर यह परिणाम मिला, तो 0 वापस आएगा। उदाहरण के लिए आप फ़ाइलें 1 एमबी बड़ी और कुछ युक्त पा सकते हैं :

find . -type f -exec grep --quiet string_to_look_for {} ';' -size 1M -print

कई आवश्यकताओं के लिए आप शायद -OGNU grep में मौजूद ऑप्टिमाइज़र ध्वज का उपयोग करना चाहते हैं ।


0

C, CPP कोड में खोजने के लिए एक स्क्रिप्ट (इन-कोड)

#!/bin/sh

find . \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" \) -type f -print0 | xargs -0 grep --color -n "$1"

उपयोग:

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