सवाल `Tail -f` के वास्तविक समय आउटपुट में फ़िल्टर कैसे लागू करें?


tail -f path

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

इस तक कैसे पहुंचे?


48
2017-07-05 09:13


मूल


स्वीकृत उत्तरों को चिह्नित करने में उन लोगों की सहायता मिलती है जो आपके प्रश्नों और उनके उत्तरों को पढ़ने में मदद करते हैं, यह जानने के लिए कि उनके उत्तर में कोई प्रश्न या समस्या होने पर उनकी सहायता करने की अधिक संभावना हो सकती है। आप अपने उपयोगकर्ता नाम पर क्लिक करके अपने पुराने प्रश्नों पर फिर से जा सकते हैं। - Dennis Williamson


जवाब:


यूनिक्स के साथ आप एक प्रोग्राम के आउटपुट को दूसरे में पाइप कर सकते हैं।

तो पूंछ फ़िल्टर करने के लिए, आप grep का उपयोग कर सकते हैं:

tail -f path | grep your-search-filter

67
2017-07-05 09:17



लेकिन मान लें कि आपके पास पूंछ (फ़ाइल के अंत) में 100 लाइनें हैं, और ये लाइनें वे फ़िल्टर हैं जिन्हें आप फ़िल्टर करना चाहते हैं। आपका समाधान - TraderJoeChicago
यदि आप केवल फ़ाइल की अंतिम 100 पंक्तियों को खोजना चाहते हैं तो tail -100 पथ का प्रयास करें grep xxx - AddersUK


संक्षिप्त जवाब: tail -f somefile | grep somepattern

हालांकि, यह कम पड़ता है। आइए मान लें कि आप एक फ़ाइल को पूंछ कर रहे हैं जो अक्सर घुमाया जाता है (यदि यह एक डीबग लॉग है, तो इसे कई बार घुमाया जा सकता है)। उस स्तिथि में tail -F आपका दोस्त है। मैं आपको अंतर देखने दूँगा।

परंतु tail -f तथा tail -F पहले लाइनों का एक समूह मुद्रित करें, जो अक्सर इस उपयोग-मामले में अवांछनीय है, इसलिए इस मामले में जोड़ें -n0

tail -F -n0 somefile | grep somepattern

यह तब तक ठीक रहेगा जब तक आप कुछ अन्य फ़िल्टरिंग नहीं करना चाहते हैं, और फिर आपको बफरिंग से सावधान रहना होगा। stdout डिफ़ॉल्ट रूप से लाइन-buffered है टर्मिनल पर लिखते समय लेकिन जब एक पाइप को लिखते समय पूरी तरह से buffered। तो जैसे ही वे पाए जाते हैं, निम्नलिखित पंक्तियों को उत्सर्जित करेंगे, क्योंकि tail स्पष्ट रूप से लाइन-बफर किया गया है (या यह प्रत्येक लाइन के अंत में अपने आउटपुट को फ्लश करता है), और grep लाइन-बफर भी है क्योंकि इसका आउटपुट आपके टर्मिनल पर जा रहा है:

tail -F -n0 somefile | grep somepattern

लेकिन फिर आप कुछ ऐसा करने का फैसला करते हैं awk या cut आउटपुट को आगे संसाधित करने के लिए।

tail -F -n0 somefile | grep somepattern | awk '{print $3}'

और अब आप सोचते हैं कि आपका आउटपुट कहां चला गया है ... लॉग की मात्रा के आधार पर, आप पाते हैं कि आपको आउटपुट मिलता है, लेकिन यह एक समय में एक पृष्ठ होगा क्योंकि अब स्टडआउट grep पूरी तरह से बफर फैशन में काम कर रहा है, और इसलिए awk इसे एक समय में इनपुट 4kB प्राप्त करता है (डिफ़ॉल्ट रूप से)।

इस मामले में, आप बता सकते हैं grep हमेशा उपयोग करके buffered stdout लाइन बनाने के लिए --line-buffered विकल्प।

tail -F -n0 somefile | grep --line-buffered somepattern | ...

हालांकि, अधिकांश आदेशों का एनालॉग नहीं होता है --line-buffered। अधिक स्क्रिप्ट योग्य टूल के मामले में, आप आउटपुट को फ्लश करने के लिए फ़ंक्शन का उपयोग कर सकते हैं (उदाहरण के लिए awk, समारोह है fflush(), जो उसके सी समकक्ष के समान नाम साझा करता है, पर्ल और पायथन जैसे टूल कुछ समान हैं)।

पसंद के साथ cut आप भाग्य से बाहर हो सकता है; ... लेकिन आप खोज करने की कोशिश कर सकते हैं unbuffer, जो मुझे लगता है कि कुछ प्रदान किया जाता है expect टूलचेन (मैंने इसका कभी भी उपयोग नहीं किया है)।

मुझे आशा है कि आपको यह उपयोगी लगेगा।

चीयर्स, कैमरून


12
2017-08-02 10:46



मैं वास्तव में स्पष्टीकरण की सराहना करता हूं क्यूं कर यह लाइन-बफर मोड में काम करता है। यह एक उत्कृष्ट अंतर्दृष्टि है, धन्यवाद। - Green
फीडबैक के लिए @ ग्रीन धन्यवाद - Cameron Kerr


और आप एकाधिक पाइप और greps का उपयोग कर सकते हैं, और grep -v के साथ चीजों को बाहर कर सकते हैं, grep -i, आदि के साथ केस असंवेदनशीलता प्राप्त करें।

अर्थात।: पूंछ -100 एफ / var / लॉग / संदेश | grep -V एसीपीआई | grep -i ata

अंत से 100 लाइनों को शुरू करना शुरू करें, और पूंछ रखें, पहले एसीपीआई के साथ किसी भी लाइन को बाहर करें, फिर एटा, एटीए, या उनमें से किसी भी मिश्रण के साथ लाइनें दिखाएं।

एक और आसान एक एबीसी विकल्प है, लाइनों के बाद, पहले, और संदर्भ (पहले और बाद में लाइनें)।


2
2017-07-05 20:12