मैं सैकड़ों PHP फ़ाइलों वाली साइट पर एक वर्ग घोषणा के लिए खोज रहा हूं। मैं वर्तमान फ़ोल्डर और सबफ़ोल्डर्स में grep का उपयोग कैसे कर सकता हूं ?
मैंने cd
फ़ोल्डर में आईएनजी का परीक्षण किया और फिर कुछ ऐसा किया
grep -r 'class MyClass' *.php
मैं सैकड़ों PHP फ़ाइलों वाली साइट पर एक वर्ग घोषणा के लिए खोज रहा हूं। मैं वर्तमान फ़ोल्डर और सबफ़ोल्डर्स में grep का उपयोग कैसे कर सकता हूं ?
मैंने cd
फ़ोल्डर में आईएनजी का परीक्षण किया और फिर कुछ ऐसा किया
grep -r 'class MyClass' *.php
जवाबों:
तुम कोशिश कर सकते हो
grep -r --include=*.php "search string" /path/to/dir
मेरा सुझाव है कि आप इसे grep के बजाय ctags की तरह उपयोग करें । हालाँकि, यदि आप चाहते हैं, तो आप कुछ ऐसा कर सकते हैं
find <top level dir> -name \*.php | xargs grep "class MyClass"
यह निश्चित रूप से मानता है कि आपके बीच केवल एक ही स्थान है class
और myClass
जो सच नहीं हो सकता है। हालांकि किसी भी व्हाट्सएप को देखने के लिए regexp को बदलना आसान है।
यदि आप उपयोग करते हैं -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 निर्देशिका।
grep -r 'class MyClass' *.php
.php के साथ समाप्त होने वाले नामों के साथ सभी फ़ोल्डरों के माध्यम से खोज करेगा
grep -r 'class MyClass' . | grep .php
सभी उप फ़ोल्डरों में सभी फाइलों में वर्ग MyClass की खोज करेगा, फिर उनमें से .php वाले को ही लौटाएगा।
find . -type f -name *.php -print -exec grep \"class MyClass\" {} \;
आपको लाइन की सामग्री को उसके फ़ाइल के पथ पर भी देगा।
संभवतः आप केस असंवेदनशीलता और व्हाट्सएप सहनशीलता चाहते हैं, और अगर यह वर्तमान निर्देशिका में वांछित फ़ाइल पैटर्न के किसी भी उदाहरण को नहीं ढूंढता है तो 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
मुझे पता है कि यह उपयोग करना कहता है grep
, लेकिन मेरा व्यक्तिगत पसंदीदा उपयोग करना है ack-grep
:
ack-grep "class MyClass"
यह पुनरावर्ती रूप से चलता है, उस फ़ाइल नाम को सूचीबद्ध करता है जिसमें परिणाम मिलते हैं, जहाँ वे पाए जाते हैं, और हाइलाइट के लिए लाइन नंबर के साथ। विशेष रूप से php फ़ाइलों को लक्षित करने के लिए जिन्हें आप चला सकते हैं:
ack-grep --type-set php:ext:php "path"
पैकेज में विकल्पों की अधिकता है; मैं निश्चित रूप से फैंसी चीजों को करने के लिए इसे (और इसके संबंधित मैन पेज को ब्राउज़ करना) सुझाऊंगा।
grep -r
उसके बारे में कुछ कहना चाह सकते हैं ।