2011-08-23 10 views
532

क्या निरंतर स्ट्रीम पर grep का उपयोग करना संभव है?एक निरंतर धारा 'grep' कैसे करें?

मेरा मतलब है कि tail -f <file> कमांड का प्रकार है, लेकिन आउटपुट पर grep के साथ ही मुझे रुचि रखने वाली लाइनों को रखने के लिए।

मैंने tail -f <file> | grep pattern की कोशिश की है लेकिन ऐसा लगता है कि grep केवल tail खत्म होने पर ही निष्पादित किया जा सकता है, जो कभी नहीं कहता है।

+29

'tail -f फ़ाइल | grep पैटर्न' बस ठीक काम करना चाहिए। –

+8

यह अत्यधिक संभावना है कि फ़ाइल उत्पन्न करने वाला प्रोग्राम अपने आउटपुट को फ्लश नहीं कर रहा है। –

+0

'tail -f फ़ाइल' काम करता है (मुझे वास्तविक समय में नया आउटपुट दिखाई देता है) –

उत्तर

989

grep की लाइन बफरिंग मोड चालू करें।

tail -f file | grep --line-buffered my_pattern 
+26

पर 'stdbuf',' unbuffer, और stdio buffering के बारे में कुछ और जानकारी यह स्वीकार्य उत्तर होना चाहिए। – Patryk

+2

क्या होता है यदि मैं एक लॉग फ़ाइल को घुमाता हूं जो घूर्णन हो जाता है, जबकि यह चल रहा है? क्या लॉगरोटेट फ़ाइल को घुमाने में सक्षम होगा? –

+3

@MichaelNiemand आप tail -F फ़ाइल का उपयोग कर सकते हैं | grep --line-buffered my_pattern – jcfrei

97

मैं हर समय tail -f <file> | grep <pattern> का उपयोग करता हूं।

यह grep flushes तक इंतजार करेगा, जब तक यह खत्म नहीं हो जाता है (मैं उबंटू का उपयोग कर रहा हूं)।

+3

मदद मिलेगी जो काफी समय तक टिक सकता है, इसलिए अधीर न होने का प्रयास करें। – glglgl

+0

इसमें कितना समय लग सकता है? –

+0

@Matthieu: मुख्य रूप से आप जो भी grep के लिए निर्भर करते हैं, और आपके ओएस पर बफर कितने बड़े हैं। यदि grep केवल कुछ ही घंटों से एक छोटी स्ट्रिंग से मेल खाता है, तो यह पहले फ्लश से कुछ दिन पहले होगा। – tripleee

0

हां, यह वास्तव में ठीक काम करेगा। Grep और अधिकांश यूनिक्स कमांड एक समय में एक पंक्ति स्ट्रीम पर काम करते हैं। पूंछ से बाहर आने वाली प्रत्येक पंक्ति का विश्लेषण किया जाएगा और यदि यह मेल खाता है तो उसे पारित किया जाएगा।

+1

यह वास्तव में सही नहीं है। यदि पाइप श्रृंखला में 'grep' अंतिम आदेश है, तो यह आपके द्वारा समझाए जाने पर कार्य करेगा। हालांकि, यदि यह मध्य में है तो यह एक समय में लगभग 8k आउटपुट बफर करेगा। –

47

मुझे लगता है कि आपकी समस्या यह है कि grep कुछ आउटपुट बफरिंग का उपयोग करता है।

tail -f file | stdbuf -o0 grep my_pattern 

यह grep के आउटपुट बफरिंग मोड को अनबफर करने के लिए सेट करेगा।

+5

और इसका लाभ यह है कि इसका उपयोग 'grep' के अलावा कई अन्य आदेशों के लिए भी किया जा सकता है। –

+4

हालांकि, जैसा कि मैंने इसके साथ और अधिक खेलने के बाद खोजा है, कुछ आदेश केवल tty से कनेक्ट होने पर अपने आउटपुट को फ्लश करते हैं, और इसके लिए, 'unbuffer'' (डेबियन पर 'अपेक्षा-dev' पैकेज में) * राजा * है। तो मैं stdbuf पर unbuffer का उपयोग करना होगा। –

+4

@ पीटर वी। मॉर्च हां, आप सही हैं, कभी-कभी काम नहीं कर सकते हैं जहां stdbuf नहीं कर सकता। लेकिन मुझे लगता है कि आप एक 'जादू' प्रोग्राम खोजने की कोशिश कर रहे हैं जो आपकी समस्या को समझने के बजाय हमेशा आपकी समस्याओं को ठीक करेगा। वर्चुअल टीटी बनाना असंबंधित कार्य है। Stdbuf वही करता है जो हम चाहते हैं (मूल्य देने के लिए मानक आउटपुट बफर सेट करता है), जबकि अनबफर कई छिपी हुई चीजें करता है जिन्हें हम नहीं चाहते हैं (stdbuf और unbuffer के साथ इंटरैक्टिव 'शीर्ष' की तुलना करें)। और वास्तव में कोई 'जादू' समाधान नहीं है: अनबफर कभी-कभी विफल रहता है, उदाहरण के लिए awk विभिन्न बफर कार्यान्वयन का उपयोग करता है (stdbuf भी असफल हो जाएगा)। – XzKto

-3

उपयोग awk (एक और महान बैश उपयोगिता) ग्रेप जहां न लाइन बफ़र विकल्प होता है के बजाय! यह पूंछ से आपके डेटा को लगातार स्ट्रीम करेगा।

इस यह आपको tail -f /var/log/some.log |grep foo और यह ठीक काम करेंगे कर सकते हैं कि कैसे आप ज्यादातर मामलों में awk

tail -f <file> | awk '/pattern/{print $0}' 
+5

यह सही नहीं है; बॉक्स के बाहर Awk लाइन बफरिंग करता है, बस अन्य मानक यूनिक्स उपकरण की तरह। (इसके अलावा, '{प्रिंट $ 0} 'अनावश्यक है, क्योंकि जब कोई शर्त गुजरती है तो प्रिंटिंग डिफ़ॉल्ट कार्रवाई होती है।) – tripleee

4

का प्रयोग करेंगे कि कैसे आप ग्रेप

tail -f <file> | grep pattern 

का उपयोग करें।

आप चल रहे एक लॉग फ़ाइल पर एक से अधिक greps उपयोग करने के लिए की जरूरत है और आप पाते हैं कि आप कोई उत्पादन मिलते हैं तो आप बीच ग्रेप (रों) में --line-buffered स्विच रहना है, तो जैसे आवश्यकता हो सकती है:

tail -f /var/log/some.log | grep --line-buffered foo | grep bar 
1

आप .. वृद्धि के रूप में इस उत्तर पर विचार कर सकते आमतौर पर मैं उपयोग कर रहा हूँ

tail -F <fileName> | grep --line-buffered <pattern> -A 3 -B 5 

एफ फ़ाइल घुमाने के मामले में बेहतर है (-f ठीक से काम नहीं करेगा अगर फाइल घुमाया)

-A और -B पैटर्न घटना से पहले और बाद में लाइनों को पाने के लिए उपयोगी है ..इन ब्लॉकों धराशायी लाइन विभाजक के बीच दिखाई होगा

+1

' grep-c 3 ', प्रतिस्थापित करता है- ए और -0 यदि एन समान है। –

-1

sed उचित आदेश होगा (धारा संपादक)

tail -n0 -f <file> | sed -n '/search string/p'

और फिर अगर आप आप एक विशेष पाया एक बार बाहर निकलने के लिए पूंछ आदेश चाहता था स्ट्रिंग:

tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'

जाहिर है एक bashism: $ मार पीआईडी ​​पूंछ कमांड की प्रक्रिया आईडी होगी। पाइप में पूंछ के बाद sed command अगली है, इसलिए sed process id $ BASHPID + 1 होगी।

+1

धारणा है कि सिस्टम पर अगली प्रक्रिया शुरू हुई ('$ BASHPID + 1') आपकी स्थितियों में कई स्थितियों में झूठी होगी, और यह बफरिंग समस्या को हल करने के लिए कुछ भी नहीं करता है, जो शायद ओपी क्या पूछने की कोशिश कर रहा था। विशेष रूप से, यहां 'grep'' पर 'sed' की सिफारिश करना केवल (संदिग्ध) वरीयता का विषय लगता है। (आप 'grep-m 1' के साथ' p; q' व्यवहार प्राप्त कर सकते हैं यदि वह बिंदु है जिसे आप वितरित करने का प्रयास कर रहे हैं।) – tripleee

2

आप पूरे फ़ाइल में मैचों (न सिर्फ पूंछ) खोजना चाहते हैं, और आप इसे बैठते हैं और किसी भी नए मैचों के लिए प्रतीक्षा करने के लिए चाहते हैं, यह अच्छी तरह से काम करता है:

tail -c +0 -f <file> | grep --line-buffered <pattern> 

-c +0 झंडा कहता है कि आउटपुट फ़ाइल की शुरुआत (+) से 0 बाइट्स (-c) शुरू करनी चाहिए।

संबंधित मुद्दे