केवल पहले मैच को रोकें और रोकें


328

मैं एक निर्देशिका की खोज कर रहा हूँ, जिसमें निम्न तर्कों के साथ grep का उपयोग करके केवल पहले मैच की वापसी की उम्मीद की जा रही है। दुर्भाग्य से, यह एक से अधिक रिटर्न - वास्तव में दो आखिरी बार जब मैंने देखा था। ऐसा लगता है कि मेरे पास बहुत सारे तर्क हैं, विशेष रूप से वांछित परिणाम प्राप्त किए बिना। : - /

# grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/directory

रिटर्न:

Pulsanti Operietur
Pulsanti Operietur

शायद grep ऐसा करने का सबसे अच्छा तरीका नहीं है? आप मुझे बताएं, बहुत बहुत धन्यवाद।

जवाबों:


510

-m 1किसी भी फ़ाइल में पहला मैच वापस मतलब है। लेकिन यह अभी भी अन्य फाइलों में खोजना जारी रखेगा। इसके अलावा, यदि एक ही पंक्ति में दो या अधिक मिलान होते हैं, तो वे सभी प्रदर्शित किए जाएंगे।

आप head -1इस समस्या को हल करने के लिए उपयोग कर सकते हैं :

grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -1

प्रत्येक grep विकल्प की व्याख्या:

-o, --only-matching, print only the matched part of the line (instead of the entire line)
-a, --text, process a binary file as if it were text
-m 1, --max-count, stop reading a file after 1 matching line
-h, --no-filename, suppress the prefixing of file names on output
-r, --recursive, read all files under a directory recursively

बहुत बढ़िया! धन्यवाद। btw - क्या वे सभी तर्क आवश्यक हैं जो मेरे पास हैं? और क्या होगा अगर मैं इसे संयोग से (बस मामले में) पाइप नहीं कर सकता।
टिम कम्म

2
मुझे नहीं लगता कि वे आवश्यक हैं ( -rस्पष्ट रूप से छोड़कर ), लेकिन उन्हें चोट नहीं पहुंचनी चाहिए ( -aहालांकि मैं इसका इस्तेमाल नहीं करूंगा )
mvp

3
बिल्कुल वही जो मुझे चाहिए था। मेरा पैटर्न एक ही पंक्ति में दो बार पाया गया और grep -m 1इस वजह से दोनों उदाहरणों को वापस कर दिया। |head -1उसे हल कर लिया!
हार्पर्विल

6
@ क्रिस_ सटीक व्यवहार उस शेल पर निर्भर करता है जिस पर आप चल रहे हैं। पहली पंक्ति से सामना करते ही सिर बाहर निकल जाएगा। grep अगली बार बाहर निकलने की कोशिश करेगा जब वह सिर से बाहर निकलने के बाद लिखने की कोशिश करेगा। कुछ शेल एक पाइपलाइन के सभी तत्वों के खत्म होने तक प्रतीक्षा करेंगे, कुछ पाइप के अंतिम कार्यक्रम के पूरा होते ही पूरे पाइप को बंद कर देंगे।
पुहलेन २४'१

1
@ 3Qn, मुझे आपकी टिप्पणी समझ में नहीं आती है first not first from result:। यह उत्तर किसी भी फाइल में पहले मैच को प्रिंट करता है और स्टॉप करता है। आपको और क्या उम्मीद थी?
mvp

31

आप grepपरिणाम को stdbufhead के साथ जोड़ सकते हैं

ध्यान दें, कि Nth मैच के बाद रुकना सुनिश्चित करने के लिए, आपको stdbufयह सुनिश्चित करने के लिए उपयोग करना होगा कि grepइसका आउटपुट बफर न करें :

stdbuf -oL grep -rl 'pattern' * | head -n1
stdbuf -oL grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -n1
stdbuf -oL grep -nH -m 1 -R "django.conf.urls.defaults" * | head -n1

जैसे ही head1 लाइन की खपत होती है, यह समाप्त हो गया और grepप्राप्त होगा SIGPIPEक्योंकि यह अभी भी पाइप में कुछ उत्पादन करता है जबकि headचला गया था।

यह मान लिया गया कि किसी फ़ाइल नाम में नई रेखा नहीं है।


मैं के साथ संग्रह फ़ाइलों की एक बड़ी संख्या में खोज करने के लिए इस समाधान को अपनाने के लिए कोशिश कर रहा हूँ xargs: find . -name '*.gz' | xargs -I '{}' stdbuf -oL zgrep -al 'pattern' {} | head -n 1। यह, हालांकि, पहले मैच पर समाप्त नहीं होता है। कोई सलाह?
DKroot

1
नहीं चाहेंगे grepके --line-bufferedविकल्प के लिए एक अतिरिक्त उपयोगिता बुला बिना भूमि के ऊपर बफ़र रोकने?
डेविड

23

मेरे grep-a-like प्रोग्राम ackमें एक -1विकल्प है जो पहले मैच में कहीं भी रुकता है। यह समर्थन करता है -m 1कि @mvp भी संदर्भित करता है। मैंने इसे वहाँ रखा क्योंकि अगर मैं स्रोत कोड का एक बड़ा पेड़ खोज रहा हूँ जो मुझे पता है कि केवल एक फ़ाइल में मौजूद है, तो इसे खोजने के लिए अनावश्यक है और Ctrl-C को हिट करना होगा।


तो आप कहेंगे कि grep की तुलना में ऐक तेज़ है? मैं वास्तव में गति कारक से भी चिंतित हूं।
टिम कम्म

1
ack grep से तेज हो सकता है, यह इस बात पर निर्भर करता है कि आप क्या खोज रहे हैं। कृपया ध्यान दें कि ack सोर्स कोड खोजने के बारे में है। यदि आप सामान्य फ़ाइलों को खोजना चाहते हैं, तो यह कम से कम अच्छा है, कम से कम ack 1.x में। ऐक के बारे में पढ़ें और देखें कि क्या यह आपकी आवश्यकताओं के अनुरूप है।
एंडी लेस्टर

2
मैं एक लंबे समय के लिए Ack का उपयोग कर रहा हूं, लेकिन हाल ही में सिल्वर खोजकर्ता पर स्विच किया गया है , जो मुझे Ack
man.gc

मेरा मानना ​​है कि यह एकमात्र उत्तर होना चाहिए क्योंकि ओपी ने कहा कि वह इसे grep के साथ करना चाहता था, लेकिन दूसरा उत्तर सिर का उपयोग करता है (निश्चित रूप से दोनों काम करता है) लेकिन न्यूनतम उपकरण के साथ कुछ एम्बेडेड / स्व-निर्मित वातावरण हैं जहां grep आम और पूंछ / है सिर नहीं है।
आरिब सो यासिर

यह उल्लेख करते हुए कि agयह तेज़ हो सकता है, लेकिन इसमें वह-1 विकल्प नहीं है जो इस मामले में उपयोगी है
jja

3

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

grep -m 1 -r "Not caching" * | head -1

2

एक एकल लाइनर, का उपयोग कर find:

find -type f -exec grep -lm1 "PATTERN" {} \; -a -quit

6
यह बहुत धीमी गति से होने जा रहा है , क्योंकि प्रत्येक फाइल के लिए grep की स्पॉन कॉपी ढूंढेगा। grep -rबहुत तेजी से काम करता है - इसकी केवल एक प्रति जो निर्देशिका ट्रैवर्सल्स करती है।
mvp

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