'Grep -q' संपूर्ण इनपुट फ़ाइल का उपभोग क्यों करता है?


23

निम्नलिखित इनपुट फ़ाइल पर विचार करें:

1
2
3
4

चल रहा है

{ grep -q 2; cat; } < infile

कुछ भी नहीं छापता। मुझे उम्मीद है कि यह प्रिंट होगा

3
4

यदि मैं इसे बदलता हूं तो मुझे अपेक्षित आउटपुट मिल सकता है

{ sed -n 2q; cat; } < infile

पहला कमांड अपेक्षित आउटपुट प्रिंट क्यों नहीं करता है?
यह एक खोजी इनपुट फ़ाइल है और विकल्प के तहत मानक के अनुसार :

-q
      Quiet. Nothing shall be written to the standard output, regardless of 
      matching lines. Exit with zero status if an input line is selected.

और नीचे, आवेदन उपयोग के तहत (मेरा जोर दें):

-qविकल्प आसानी से निर्धारित करने या नहीं, एक पैटर्न (या स्ट्रिंग) फ़ाइलों के एक समूह में मौजूद है के एक साधन के प्रदान करता है। कई फ़ाइलों की खोज करते समय, यह एक प्रदर्शन सुधार प्रदान करता है ( क्योंकि यह पहला मैच पाते ही छोड़ सकता है ) [...]

अब, एक ही मानक के अनुसार (में परिचय , के तहत इनपुट फ़ाइलें )

जब एक मानक उपयोगिता एक शोध योग्य इनपुट फ़ाइल को पढ़ती है और एक त्रुटि के बिना समाप्त हो जाती है, तो यह फ़ाइल के अंत तक पहुंचने से पहले, उपयोगिता सुनिश्चित करेगी कि खुले फ़ाइल विवरण में फ़ाइल ऑफ़सेट उपयोगिता द्वारा संसाधित अंतिम बाइट से ठीक पहले स्थित है । ..]

tail -n +2 file
(sed -n 1q; cat) < file
...

दूसरा कमांड केवल उसी के बराबर है जब फ़ाइल की तलाश हो।


grep -qपूरी फ़ाइल का उपभोग क्यों करता है ?


यह तब होता है gnu grepजब यह मायने रखता है (हालांकि कुसलानंद ने पुष्टि की कि ओपनबीएसडी पर भी ऐसा ही होता है)


OpenBSD की grepकुछ चीज़ों का एक कांटा है , जिसे FreeGrep कहा जाता है , अगर किसी को आश्चर्य होता है।
Kusalananda

जवाबों:


37

grep यह जल्दी बंद हो जाता है, लेकिन यह इसके इनपुट को बफ़र करता है, इसलिए आपका परीक्षण बहुत कम है (और हाँ, मुझे पता है कि मेरा परीक्षण अपूर्ण है क्योंकि यह खोजी नहीं है):

seq 1 10000 | (grep -q 2; cat)

मेरे सिस्टम पर 6776 से शुरू होता है। ग्नू ग्रीप में डिफ़ॉल्ट रूप से उपयोग किए जाने वाले 32KiB बफर से मेल खाता है :

seq 1 6775 | wc

आउटपुट

   6775    6775   32768

ध्यान दें कि POSIX में केवल प्रदर्शन सुधार का उल्लेख है

जब कई फाइलें खोज रहे हैं

आंशिक रूप से किसी एकल फ़ाइल को पढ़ने के कारण प्रदर्शन में सुधार के लिए कोई अपेक्षा नहीं करता है।


2

यह स्पष्ट रूप से बफरिंग के कारण है जो grepचीजों को गति देने के लिए करता है। ऐसे उपकरण हैं जो विशेष रूप से अनुरोध किए गए और अधिक नहीं के रूप में कई वर्णों को पढ़ने के लिए डिज़ाइन किए गए हैं। उनमें से एक है expect:

{ expect -c "log_user 0; expect 2"; cat; } < infile

मेरे पास इस पर प्रयास करने के लिए एक प्रणाली नहीं है, लेकिन मेरा मानना ​​है कि expectजब तक यह अपेक्षित स्ट्रिंग ( 2) का सामना नहीं करता है , तब तक सब कुछ खा जाएगा , और फिर समाप्त हो जाएगा, इसके लिए बाकी इनपुट छोड़ दें cat


1

आप sed और grep को भ्रमित कर रहे हैं।

सेड कमांड के लिए, -2qयह कह रहा है कि वर्तमान पुनरावृत्ति को छोड़ दें यदि दूसरी पंक्ति में, -nविकल्प चुपचाप कार्य करने के लिए कह रहा है, तो आपको 2 के बाद सभी लाइनें मिलेंगी।

Grep कमांड सभी मिलान लाइनों को आउटपुट करने के लिए डिफ़ॉल्ट रूप से चलती है - लेकिन -qविकल्प स्टैडआउट को कुछ भी आउटपुट नहीं करने के लिए कहता है। इसलिए, यदि इनपुट में "2" है, तो इसमें SUCCESS का निकास मान होगा, अन्यथा विफल। वे जो आपके ऑपरेटिंग सिस्टम और शेल पर निर्भर हैं। इसलिए, आम तौर पर आप बताएंगे कि क्या grep प्रक्रिया के निकास मान की जांच करके कोई रेखा मेल खाती है। यह एक पाइपलाइन में उपयोगी है जहां आप जानना चाहते हैं कि क्या आपके इनपुट में परीक्षण के रूप में कुछ मूल्य है। उदाहरण के लिए

if grep -q 'crash' <somelog.log ; then report_crash_via_email ; fi

इस मामले में हम वास्तव में सभी मिलान लाइनों को देखने के लिए परवाह नहीं करते हैं, हम बस परवाह करते हैं यदि कम से कम एक मौजूद है। report_crash_via_emailप्रक्रिया / समारोह तो दूर जा सकते हैं और फ़ाइल को फिर खोल सकता है या नहीं।

यदि आप "2" वर्ण ढूंढने के बाद अपनी grep प्रक्रिया चाहते हैं - तो यह डिफ़ॉल्ट रूप से नहीं होगा, यह देखने वाली प्रत्येक पंक्ति का निरीक्षण करेगा कि क्या यह मेल खाता है - आपको इसे करने के लिए यह बताने की आवश्यकता है। इसके लिए कमांड लाइन स्विच है -m <value>। आपके मामले के लिए तो, grep -q -m1 2


6
आपका उत्तर सामान्य उपयोग के लिए उपयोगी जानकारी है, grepलेकिन यह प्रश्न कुछ अधिक सूक्ष्म और गूढ़ के बारे में पूछ रहा है। ऐसा लगता है कि आपने वास्तविक व्यवहार को समझने के लिए प्रश्न को बहुत तेज़ी से पढ़ा है। इसके अलावा, जीएनयू grep करता है जब साथ प्रयोग किया स्टॉप खोज -q(के रूप में POSIX विनिर्देशन से बोली में अनुमति दी): जीएनयू ग्रेप राज्यों के लिए आदमी पृष्ठ है कि यह "बाहर निकलें तुरंत शून्य की स्थिति के साथ यदि कोई मिलान हो जाता है [एस]" । FWIW, मैंने आपके प्रश्न को यह दिखाने के लिए संपादित किया है कि आप भविष्य की पोस्ट को कैसे प्रारूपित कर सकते हैं। स्टैक एक्सचेंज में वेलकम ।
एंथनी जी - मोनिका के लिए न्याय

उस ने कहा, @ user212377 का उत्तर सही है: इस उदाहरण grepमें पूछा जा रहा है कि क्या फ़ाइल में '2' मौजूद है, इससे अधिक और कुछ भी कम नहीं है। यह उस तरह का व्यवहार नहीं करता है sedऔर उस बिंदु तक रिकॉर्ड का उपभोग करता है और आगे की प्रक्रिया के लिए शेष छोड़ देता है। यह तब तक पढ़ता है जब तक यह पता नहीं हो जाता है कि '2' है या नहीं है, फ़ाइल बंद कर देता है, और परिणाम देता है।
कीथ डेविस

grepवास्तव में केवल 'संपूर्ण फ़ाइल का उपभोग करता है' (यदि बफ़रिंग को ध्यान में न रखते हुए) यदि खोज स्ट्रिंग फ़ाइल में मौजूद नहीं है (जो पूरी फ़ाइल की जाँच करके ही साबित होती है)। कुछ भी कम जो कि, फ़ाइल पढ़ना बंद हो जाता है , फ़ाइल बंद हो जाती है, और SUCCESS वापस आ जाता है।
कीथ डेविस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.