वहाँ एक निर्देशिका के तहत सभी फ़ाइलों को grep करने का एक सरल तरीका है?


21

जब मैं कुछ सामग्री के लिए एक पूरे पेड़ को खोजना चाहता हूं, तो मैं उपयोग करता हूं

find . -type f -print0 | xargs -0 grep <search_string>

क्या प्रदर्शन या संक्षिप्तता के संदर्भ में ऐसा करने का बेहतर तरीका है?


2
@Downvoter: यदि आप अपनी चिंताओं को साझा कर सकते हैं तो इस प्रश्न को सुधारने में खुशी होगी।
दंक्रम्ब

2
कई खोज संस्करणों में निर्मित xargs है: खोजें। -टाइप f -exec fgrep <search_string> {} +
simpleuser

जवाबों:


42

जांचें कि क्या आपका grepसमर्थन -rविकल्प ( पुनर्खरीद के लिए ):

grep -r <search_string> .

1
हाँ ... मुझे बस stackoverflow.com/questions/16956810/… मिला है और वहां भी यही जवाब है।
१anc

--exclude-dirप्रदर्शन को संबोधित करने के बारे में एक टिप्पणी जोड़ें और हमारे पास एक विजेता है!
Dancrumb

1
बस ध्यान दें कि यह पोर्टेबल नहीं है, हालांकि grepहाल के फ्रीबीएसडी और लिनक्स डिस्ट्रोस इसका समर्थन करते हैं। और क्यों --exclude-dir? क्या आपने एक पूरे पेड़ की खोज करने के लिए नहीं कहा ?
फिलिप्प्स

फेयर पॉइंट ... --exclude-dirवास्तव में मेरे उपयोग के मामले में बहुत उपयोगी है (क्योंकि सबट्री के हिस्से बड़े हैं, लेकिन बेकार हैं) और मैंने प्रदर्शन के बारे में पूछा ... लेकिन आप सही हैं, यह आवश्यक नहीं है।
Dancrumb

इस मामले में मुझे यह जोड़ना है कि IIRC --exclude-dirGNU के लिए अनन्य है grep। (-:
फिलिप्पियों

13

एक उप इष्टतम जवाब: के उत्पादन में पाइप के बजाय findमें grep, तुम बस चला सकते हैं

find . -type f -exec grep 'research' {} '+'

और वॉइला, दो के बजाय एक कमांड!

स्पष्टीकरण:

find . -type f

सभी नियमित फ़ाइलें खोजें।

-exec grep 'research'

grep 'शोध'

{}

फ़ाइल नाम में

'+'

सभी फ़ाइलनामों में से एक आदेश का उपयोग करें, एक बार फ़ाइलनाम के अनुसार नहीं।

नायब: साथ ';' एक बार फ़ाइल नाम दिया गया होगा।

इसके अलावा, यदि आप स्रोत कोड को संसाधित करने के लिए इसका उपयोग करते हैं, तो आप देख सकते हैं ack, जो आसानी से कोड बिट्स की तलाश के लिए बना है।

एसीके

संपादित करें:

आप उस शोध को थोड़ा बढ़ा सकते हैं। सबसे पहले, आप के -name ''स्विच का उपयोग कर सकते हैंfind निर्दिष्ट नामकरण पैटर्न के साथ फ़ाइलों को देखने के लिए ।

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

  • केवल फ़ाइलें जो लॉग के अनुरूप हैं: -name '*.log'

  • केवल फाइलें जो हेडर के अनुरूप हैं, लेकिन आप अपने फ़ाइल एक्सटेंशन के लिए अपरकेस या लोअरकेस के साथ नहीं चिपक सकते हैं: -iname *.c

Nb: like grepऔर ack, के लिए-i स्विच का अर्थ है इस मामले में असंवेदनशील।

उस स्थिति में, grep बिना रंग और बिना लाइन नंबर के दिखाई देगा।

आप इसे --colorऔर के साथ बदल सकते हैं-n स्विच के साथ (क्रमशः फाइलों में रंग और रेखाएं)।

अंत में, आपके पास कुछ इस तरह हो सकता है:

find . -name '*.log' -type f -exec grep --color -n 'pattern' {} '+'

उदाहरण के लिए

$ find . -name '*.c' -type f -exec grep -n 'hello' {} '+' 
./test2/target.c:1:hello

5
ackमहान है, और (सिल्वर सर्चर , जियॉफ.ग्रेअर.फम / ag ) का एक तेज़ संस्करण ackहैag
cfeduke

1
मैं -name '*.log'इसे फिल्टर के साथ पसंद करता हूं जैसे यह तेज है।
sdkks

@cfeduke मैंने इसे आज़माया नहीं है, ज्यादातर इसलिए कि WS WSL पर डिफ़ॉल्ट एपेट रिपॉजिटरी का हिस्सा नहीं है (आपको जो मिल गया है उसके साथ काम करना होगा!)
पियरे-एंटोनी

छल करने के लिए grep को जोड़ने के लिए एक ट्रिक / dev / null जोड़ना है।

एक तरकीब केवल निर्देशिका के लिए खोज करना है और फिर -ex grep / dev / null {} / * के लिए सभी फ़ाइलों को एकल कांटा / निर्देशिका के साथ निष्पादित करने के लिए प्राप्त करना है।
ChuckCottrill

12

यदि आप उपनिर्देशिका में नीचे जाना चाहते हैं:

grep -R 'pattern' .

-Rविकल्प के लिए एक मानक विकल्प नहीं है, लेकिन सबसे आम द्वारा समर्थित है grepकार्यान्वयन।


7
जब GNU grep चिंतित हो तो -r-R
सिम्फ़लिंक

1
@AFSHIN आप क्यों सहानुभूति का पालन नहीं करना चाहेंगे?
Kusalananda

4
@ कुसलानंद पुनर्मिलन? हालांकि वर्तमान जीएनयू grepकार्यान्वयन पुनरावृत्ति पकड़ते हैं, मुझे लगता है। अन्यथा यह निर्भर करता है कि आप "पेड़" से क्या मतलब है।
फिलीपोस

2
@Philippos IMHO, उपयोगकर्ता को बचकाना कुछ ऐसा नहीं है जो एक उपकरण को grepकरना चाहिए। उपयोगकर्ता अपने निर्देशिका संरचना में प्रतीकात्मक कड़ी छोरों है, तो अच्छी तरह से, उस उपयोगकर्ता के समस्या है :-)
Kusalananda

3
@ कुसलानंद और अगर सिस्टम ने लूप प्रदान किया? कभी भी /sys/devices/cpu/subsystem/devices/cpu/subsystem/devices/cpu/...(-XI में ) मुझे खो देने वाले औजारों की तरह नहीं खोया (जब तक कि वे अजीब जादू वे "एआई" नहीं कहते) - (-;
फिलिप्पुस

5

जैसा कि ऊपर उल्लेख किया गया है -rया -R(वांछित सिम्बलिन हैंडलिंग के आधार पर) एक त्वरित विकल्प है।

हालांकि -d <action>कई बार उपयोगी हो सकता है।

-dजब आप वर्तमान स्तर को स्कैन करना चाहते हैं, तो अच्छी बात यह है कि स्किप कमांड है, जो "grep: directory_name: एक निर्देशिका" है।

$ grep foo * 
grep: q2: Is a directory 
grep: rt: Is a directory 

$ grep -d skip foo *  
$ 

और निश्चित रूप से:

$ grep -d recurse foo * 
(list of results that don't exist because the word foo isn't in our source code
and I wouldn't publish it anyway).  
$ 

-d skipविकल्प एक और स्क्रिप्ट के अंदर वास्तव में काम तो आप की जरूरत नहीं है है 2> /dev/null। :)


0

यदि आप बहुत सारी फ़ाइलों के साथ काम कर रहे हैं, तो grep तेजी से चलता है यदि आप उन फ़ाइलों को नीचे दबा देते हैं, जिन्हें सबफ़ोल्डर्स में सभी फ़ाइलों को छोड़ने के बजाय खोज करने की आवश्यकता होती है।

मैं कभी-कभी इस प्रारूप का उपयोग करता हूं:

grep "primary" `find . | grep cpp$`

.उस अंत के सबफ़ोल्डर में सभी फ़ाइलें खोजें cpp। फिर "प्राथमिक" के लिए उन फ़ाइलों को grep करें।

यदि आप चाहें, तो आप उन परिणामों को आगे के grep कॉल में पाइप कर सकते हैं:

grep "primary" `find . | grep cpp$` | grep -v "ignoreThis" | grep -i "caseInsensitiveGrep"

1
बैकटिक्स अच्छे आधुनिक अभ्यास नहीं हैं, वे सभी अप्रचलित हैं
क्रिस्टोफर

1
यह टूट जाएगा यदि आपके पास उनके नामों में विशेष वर्णों वाली फाइलें हैं। मुझे नहीं पता कि इस तरह से काम करने के लिए उन्हें कितना विशेष होना पड़ता है, लेकिन जैसा कि आप कर रहे हैं, वास्तव में एलएस के उत्पादन को पार्स करने के समान ही है, जो खराब भी है।
एक CVn
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.