मैं `grep` का उपयोग करके PHP फ़ाइल में स्ट्रिंग की खोज कैसे करूँ?


11

मैं सैकड़ों PHP फ़ाइलों वाली साइट पर एक वर्ग घोषणा के लिए खोज रहा हूं। मैं वर्तमान फ़ोल्डर और सबफ़ोल्डर्स में grep का उपयोग कैसे कर सकता हूं ?

मैंने cdफ़ोल्डर में आईएनजी का परीक्षण किया और फिर कुछ ऐसा किया

grep -r 'class MyClass' *.php

जब यह सुपरयुसर के पास जाता है, तो आप जो चाहते थे, grep -rउसके बारे में कुछ कहना चाह सकते हैं ।

मैं असमंजस में हूँ - क्या आपने सिर्फ अपने आप को जवाब नहीं दिया? उस लाइन के परिणाम क्या थे? क्या आप इसे और बेहतर बनाने की कोशिश कर रहे हैं? कृपया इस प्रश्न को किसी और के रूप में पढ़ने की कल्पना करें, क्योंकि यह भ्रमित और अस्पष्ट है।
मध्यकाल

@ अन्य टिप्पणियां: उसका grep -r स्टेटमेंट वह नहीं दे रहा है जो वह चाहता है, जब तक कि सभी फ़ोल्डर्स .php के साथ समाप्त न हों, जो कि संभवत: ऐसा नहीं है ...
डेविड वनिल

मुझे कुछ भी नहीं मिला। मुझे लगता है कि यह काम नहीं किया क्योंकि मुझे पता है कि यह उस फोल्डर पर im लगता है, जिसमें इस वर्ग के साथ फाइल है

मुझे किस्मत से फाइल मिली। जब उस लाइन के साथ PHP फ़ाइल वाले फ़ोल्डर में फ़ाइल की खोज की जाती है, तो वह इसे ढूँढता है (-r की कोई आवश्यकता नहीं)। अगर मैं रूट करने के लिए सीडी और पुनरावृत्ति के साथ खोज करते हैं, तो यह कुछ भी वापस नहीं करता है।

जवाबों:


24

तुम कोशिश कर सकते हो

grep -r --include=*.php "search string" /path/to/dir

1
बहुत अच्छा काम करता है। मैं भूलता रहता हूं, लेकिन सौभाग्य से मेरी मदद करने के लिए हमेशा यही जवाब है। :)
गोलेज़ट्रॉल २

@GolezTrol खुशी है कि पता करने के लिए :-)
rahul286

9

मेरा सुझाव है कि आप इसे grep के बजाय ctags की तरह उपयोग करें । हालाँकि, यदि आप चाहते हैं, तो आप कुछ ऐसा कर सकते हैं

 find <top level dir> -name \*.php | xargs grep "class MyClass"

यह निश्चित रूप से मानता है कि आपके बीच केवल एक ही स्थान है classऔर myClassजो सच नहीं हो सकता है। हालांकि किसी भी व्हाट्सएप को देखने के लिए regexp को बदलना आसान है।


4

यदि आप उपयोग करते हैं -r, तो आप शायद वर्तमान निर्देशिका को पुन: खोज करना चाहते हैं :

grep -r 'class MyClass' .

उपरोक्त के अंत में अवधि पर ध्यान दें।

आपने जो बताया grepवह यह था कि आप चाहते थे कि यह हर *.phpफ़ाइल या निर्देशिका को पुन: खोजा जाए , लेकिन संभवतः आपके पास कोई निर्देशिका नहीं थी जो एक .pp एक्सटेंशन में समाप्त हो गई थी। उपरोक्त खोज करने का सबसे सरल संभव तरीका है, लेकिन इसमें अन्य प्रकार की फाइलें भी शामिल हैं जो विशेष रूप से समस्याग्रस्त होती हैं जब आपके पास .svn निर्देशिकाएं हर जगह होती हैं। यदि आपके पास बहुत अधिक अन्य प्रकार के फ़ाइल नहीं हैं, तो ऊपर आम तौर पर पर्याप्त है और अच्छी तरह से काम करता है।

Grep के अधिकांश अवतारों में फ़ाइल एक्सटेंशन को निर्दिष्ट करने का एक तरीका नहीं है जिसे खोजा जा सकता है, इसलिए आप आम तौर पर इसके साथ संयोजन में उपयोग करते हैं:

find <startDir> -iname '*.php' -exec grep 'class[ \t]*MyClass' {} \;

-inameजीआरईपी के कुछ संस्करणों को बताता है कि आप केस-असंवेदनशील फ़ाइलनाम खोज करना चाहते हैं, लेकिन गैर-जीएनयू संस्करण के कई खोज इसका समर्थन नहीं करते हैं, इसलिए आप -nameइसके बजाय उपयोग कर सकते हैं ।

-execविकल्प के ऊपर हर फ़ाइल है, जो काफी महंगा है के लिए ग्रेप लागू की ओर प्रभाव पड़ता है।

अभी भी grep के अन्य संस्करण समर्थन करते हैं +जो बताता है कि निष्पादन योग्य के चालान की संख्या को कम करने के लिए तर्कों को एक साथ जोड़ना है:

find <startDir> -iname '*.php' -exec grep 'class[ \t]*MyClass' {} + \;

इनवोकेशन को कम करने के लिए अक्सर अनुशंसित तरीका xargs का उपयोग करना होता है जो संभव के रूप में कई बार grep को बंद कर देगा लेकिन कई बार आवश्यक:

find <startDir> -iname \*.php | xargs grep "class[ \t]*MyClass"

xargsकमांड लाइन पर समर्थित तर्कों की अधिकतम संख्या तक grep पास करने के लिए पर्याप्त स्मार्ट है, लेकिन उपरोक्त भिन्नता कुछ वर्णों जैसे रिक्त स्थान को बहुत अच्छी तरह से नहीं संभालती है। उदाहरण के लिए, 'file.php' एक फ़ाइल नाम grep को 'एक तर्क के रूप में' और 'file.php' को एक तर्क के रूप में प्राप्त होगा, इसलिए दोनों नहीं मिलेंगे। इसके बजाय हम उपयोग करते हैं:

find <startDir> -iname \*.php -print0 | xargs -0 grep "class[ \t]*MyClass"

print0और -0एक साथ काम करते हैं और एक अशक्त चरित्र द्वारा पीछा तर्क का उपयोग करते हैं ताकि तर्क पूरी तरह से और स्पष्ट रूप से पहचाना जाए।

f आपके पास कभी भी एक से अधिक स्थान classया टैब के बाद , आप regex को बदलकर अधिक वर्णों को अनुमति देना चाह सकते हैं:class[ \t]*MyClass

StackOverflow पर इस पोस्ट के अन्य उदाहरण हैं और यह दर्शाता है कि कुछ निर्देशिकाओं को कैसे अलग करना है, जैसे कि .vn निर्देशिका।


यह सभी फाइलों को खोजता है। साथ ही ऐसी फाइलें जो .php फाइलें नहीं हैं।
गोलेज़ट्रॉल

मैंने कई अन्य उदाहरणों को शामिल करने के लिए पोस्ट को अपडेट किया है।
कालेब पेडरसन


1
grep -r 'class MyClass' *.php

.php के साथ समाप्त होने वाले नामों के साथ सभी फ़ोल्डरों के माध्यम से खोज करेगा

grep -r 'class MyClass' . | grep .php

सभी उप फ़ोल्डरों में सभी फाइलों में वर्ग MyClass की खोज करेगा, फिर उनमें से .php वाले को ही लौटाएगा।


1

find . -type f -name *.php -print -exec grep \"class MyClass\" {} \; आपको लाइन की सामग्री को उसके फ़ाइल के पथ पर भी देगा।


1

यदि मिलान की गई फ़ाइलों में मनमानी नाम हो सकते हैं, तो आपको उपयोग करने पर विचार करना चाहिए -print0

खोजो। -Type f -name '* .php' -print0 | xargs -0 grep 'वर्ग MyClass'


1
grep -rl 'class MyClass' . --include \*.php

l केवल फ़ाइल नाम दिखाता है

आर पुनरावर्ती है

। वर्तमान फ़ोल्डर में खोज करता है

- फ़ाइल नाम एक्सटेंशन को सीमित करें


1

संभवतः आप केस असंवेदनशीलता और व्हाट्सएप सहनशीलता चाहते हैं, और अगर यह वर्तमान निर्देशिका में वांछित फ़ाइल पैटर्न के किसी भी उदाहरण को नहीं ढूंढता है तो grep समाप्त हो जाएगा। यह जानने की जरूरत है कि कहां से शुरू किया जाए, जैसा कि था, और कोई भी मिलान की गई फ़ाइल कोई आरंभिक पथ नहीं बनाती है।

यदि वांछित एक्सटेंशन की कम से कम एक फ़ाइल है, तो आप egrep -ir का उपयोग कर सकते हैं। findऔर xargsएकल फ्लैट (लेकिन बहुत बड़ी) निर्देशिकाओं के साथ अपनी शक्ति दिखाएं जो कि grep पर और अतिरिक्त क्वालीफायर पर विफल रहता है (उदाहरण के लिए यदि आप .inc, .php और php3 फ़ाइलों को केवल खोजना चाहते हैं)। लेकिन यह मेरे अनुभव में काफी सुविधा और गति खो देता है। मानव लिखित वर्ग की घोषणाओं के लिए एक बड़ी समस्या व्हाट्सएप होना है। इसलिए grep की जगह egrep का इस्तेमाल करें। अतिरिक्त गति के लिए भी LC_ALL = C। सुविधा के लिए, मैं अक्सर उपयोग करता हूं:

LC_ALL=C egrep -irn "class[ ]*myclass([ ]|\n)" * | egrep "\.(inc|php[35]?)"

-i -- case insensitive
-r -- recursive for all file pattern (here *)
-n -- include the line number
LC_ALL=C -- search in ASCII, not in utf8, this is much faster.

[ ]* -- match any number of spaces before the class name
([ ]|\n) -- match a space or newline after the classname

यह अभी भी टिप्पणियों से मेल खा सकता है, जैसे कि // class myclass exists in file, लेकिन मुझे लगता है कि वे अपेक्षाकृत छोटे हैं, और उन्हें बाहर फ़िल्टर किया जा सकता है... | fgrep -v '//'

आप अधिक जटिल फ़ाइल मास्क भी शामिल कर सकते हैं (उदाहरण के लिए, अधिकांश .inc और .php फ़ाइलों को पकड़ने के लिए) जैसे कि egrep फ़ाइल पैटर्न पर:

egrep "pattern" *.[ip]*

वह (पहले विकल्पों के साथ) काफी तेज होगा और ज्यादातर php फाइलों तक ही सीमित रहेगा।

HTH


0

मुझे पता है कि यह उपयोग करना कहता है grep, लेकिन मेरा व्यक्तिगत पसंदीदा उपयोग करना है ack-grep:

ack-grep "class MyClass"

यह पुनरावर्ती रूप से चलता है, उस फ़ाइल नाम को सूचीबद्ध करता है जिसमें परिणाम मिलते हैं, जहाँ वे पाए जाते हैं, और हाइलाइट के लिए लाइन नंबर के साथ। विशेष रूप से php फ़ाइलों को लक्षित करने के लिए जिन्हें आप चला सकते हैं:

ack-grep --type-set php:ext:php "path"

पैकेज में विकल्पों की अधिकता है; मैं निश्चित रूप से फैंसी चीजों को करने के लिए इसे (और इसके संबंधित मैन पेज को ब्राउज़ करना) सुझाऊंगा।

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