regex एसईडी और जीआरईपी अलग परिणाम दिखाते हैं




sed grep (3)

जैसा कि टिप्पणियों में बताया गया है, आप कई अभिव्यक्तियों के लिए खोज रहे हैं, और शुरू के पहले मैच से लेकर अंत तक के पहले मैच तक सभी लाइनों को मैच करेंगे। अपनी खुद की भाषा के रूप में, awk sed से अधिक लचीलेपन प्रदान करता है:

start=26/Apr/2017:08:00:21
end=26/Apr/2017:08:02:04
awk -v "s=$start" -v "e=$end" '$0~s{m=1} $0~e{m=0; f=1; print} f&&$0!~e{exit} m' access.log

हमारे पास 4 सशर्त ब्लॉक्स हैं पहले हम शुरूआत में एक मैच की जांच करते हैं और m सेट करते हैं इसके बाद हम अंत पर एक मैच की जांच करते हैं और m सेट नहीं करते हैं, f सेट करते हैं, और प्रिंटिंग जारी रखते हैं। अगले चेक f लिए f , जब तक अंत में कोई मैच नहीं होता है। यह इंगित करता है कि हमने अंतिम स्ट्रिंग के लिए सभी मैचों को समाप्त कर दिया है और छोड़ सकते हैं अंतिम ब्लॉक की जांच करता है कि अगर m सेट हो जाता है, और प्रिंट करता है तो यह है।

एक ही प्रोग्राम का एक और वर्बोस संस्करण:

awk -v "start_date=$start" -v "end_date=$end" '
{
    if ($0 ~ start_date) {
        matching = 1;
    }
    else if ($0 ~ end_date) {
        matching = 0;
        finishing = 1;
        print $0;
    }
    else if (finishing) {
        exit;
    }
    if (matching) {
        print $0;
    }
}
' access.log

टिप्पणी में सिर पर मुझे मारने के लिए @ सल्वीट्स का धन्यवाद जब तक मुझे कोई बेहतर समाधान नहीं मिला!

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

यहाँ grep कमांड है जो मैंने इस्तेमाल किया है:

#grep '26/Apr/2017:08:0[0-2]:[0-2][0-4]' access.log 

10.51.32.104 - - [26/Apr/2017:08:00:21 +0100] "GET / HTTP/1.1" 301 762 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"
10.51.32.104 - - [26/Apr/2017:08:00:22 +0100] "GET /index.php?action=Login&module=Users HTTP/1.1" 200 6591 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"
172.30.180.113 - - [26/Apr/2017:08:02:04 +0100] "GET / HTTP/1.0" 301 1906 "-" "Mozilla/4.0 (compatible; ipMonitor 10.7)"
172.30.180.113 - - [26/Apr/2017:08:02:04 +0100] "GET /index.php?action=Login&module=Users HTTP/1.0" 200 21951 "-" "Mozilla/4.0 (compatible; ipMonitor 10.7)"

और यहां कमांड है:

#sed -n '/26\/Apr\/2017:08:00:21/ , /26\/Apr\/2017:08:02:04/p' access.log

10.51.32.104 - - [26/Apr/2017:08:00:21 +0100] "GET / HTTP/1.1" 301 762 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"
10.51.32.104 - - [26/Apr/2017:08:00:22 +0100] "GET /index.php?action=Login&module=Users HTTP/1.1" 200 6591 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"
172.30.180.113 - - [26/Apr/2017:08:02:04 +0100] "GET / HTTP/1.0" 301 1906 "-" "Mozilla/4.0 (compatible; ipMonitor 10.7)"

इसलिए, जैसा कि आप देख सकते हैं कि यह एक प्रवेश 172.30.180.113 से अनुपलब्ध है जो पैटर्न से मेल खाता है।

मैंने गलत क्या किया? सैम में कोई अन्य पैरामीटर होगा, या क्या यह करने का एक बेहतर तरीका है?


हां, ऐसा करने का एक बेहतर तरीका है (जो मैं नीचे बताता हूं)। चूंकि सिफ़ारिश स्टैक ओवरफ्लो के लिए ऑफ-विषय होगा, मैं सिर्फ एक स्पष्टीकरण के साथ उत्तर दूंगा क्योंकि आपके द्वारा प्रदान किए गए कोड में क्या हो रहा है।

आपका grep कमांड इनपुट की हर पंक्ति प्रिंट करती है जो आपके द्वारा निर्दिष्ट रेगुलर एक्सप्रेशन से मेल खाती है। हालांकि यह काम करता है, यह कभी-कभी मुश्किलें निर्दिष्ट करता है कि विशुद्ध रूप से रीगेक्स में। (आप 10 जनवरी से 2 मार्च तक एक श्रेणी कैसे निर्दिष्ट करेंगे?)

एक sed कमांड एक tad अधिक जटिल हो सकता है निम्नलिखित को धयान मे रखते हुए:

$ sed -n -e '/re/p'

यह सभी लाइनों को प्रिंट करेगा जो रेगुलर एक्सप्रेशन से मेल खाती हैं। असल में grep के समान

$ sed -n -e '/re1/,/re2/p'

यह re1 के पहले मैच से re1 होने वाली सभी लाइनों को प्रिंट करेगा और पहले 2 के पहले मैच के साथ समाप्त होगा। आपके सवाल में ये क्या लिप स्क्रिप्ट है ध्यान दें कि इसमें उन पंक्तियों को मुद्रित करने की भी क्षमता है जो नियमित अभिव्यक्तियों में से एक से मेल नहीं खाती हैं:

$ printf 'one\ntwo\nthree\nfour\n' | sed -ne '/one/,/three/p'
one
two
three

यदि आप sed के उपयोग से अपने लॉग में लाइनों की गणना करना चाहते हैं, तो मैं एक वैकल्पिक दृष्टिकोण सुझाता हूं। जबकि sed पैटर्न मिलान के लिए महान है, यह उपकरण प्रदान नहीं करता है जो तिथियों की व्याख्या कर सकता है। पर्ल, या गाव, या यहां तक ​​कि बाश भी अधिक कार्यक्षमता प्रदान करते हैं, और जब आपको अपने कोड में बदलाव करने की आवश्यकता होती है, तब से छह माह को समझना / डीबग करना आसान हो जाएगा।


आप sed उपयोग से इसे सुलझाने के काफी करीब हैं। यह अच्छी शुरुआत है और मैं आपको उस मार्ग पर जाने में प्रोत्साहित करूंगा।

बेशक आप regex उपयोग कर सकते हैं लेकिन इसकी सीमा है सीमा 08:00 से 09:59 पर विचार करें, regex आसान होगा 0[89]:[0-5][09] । लेकिन यदि सीमा 08:45 से 09:30 , तो फिर से आपका फोन नहीं होगा। इसलिए, मैंने कोशिश की थी कि सीमा का उपयोग करने के लिए मेरा प्रोत्साहन।

sed साथ आप जो सीमा देख चुके हैं वह है कि अंत की सीमा पूरी हो गई है और sed ने वहां से प्रसंस्करण बंद कर दिया है। लेकिन हम जानते हैं कि अंत की सीमा के भीतर आने वाली अधिक लाइनें हो सकती हैं

sed -n '/26\/Apr\/2017:08:00:21/,/26\/Apr\/2017:08:02:04/{p;b};/26\/Apr\/2017:08:02:04/p' access.log

Sed कमांड को तोड़कर:

/26\/Apr\/2017:08:00:21/,/26\/Apr\/2017:08:02:04/{p;b}

यह सीमा के भीतर लाइन और फिर b ranch sed कमांड के अंत करने के लिए लाइन प्रिंट जाएगा।

/26\/Apr\/2017:08:02:04/p

यह पिछले sed कमांड में सीमा के बाहर अगर केवल निष्पादित होगा। यह सीमा के भीतर आने वाली अतिरिक्त लाइनों का ध्यान रखेगा लेकिन इसे sed अंतर्गत नहीं माना जाएगा।

एक ही तकनीक का इस्तेमाल awk साथ किया जा सकता है।

awk '/26\/Apr\/2017:08:00:21/,/26\/Apr\/2017:08:02:04/{a=NR;print};a!=NR && /26\/Apr\/2017:08:02:04/{print}' access.log

पहला आदेश:

/26\/Apr\/2017:08:00:21/,/26\/Apr\/2017:08:02:04/{a=NR;print}

सीमा के भीतर लाइनों को प्रिंट करें और NR (वर्तमान रिकॉर्ड संख्या) के मूल्य में वैरिएबल को निर्धारित करें।

दूसरा आदेश:

a!=NR && /26\/Apr\/2017:08:02:04/{print}

रेंज के बाहर की शेष लाइनों को प्रिंट करेंगे, लेकिन रेंज के बाहर माना जाने वाला awk







grep