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




sed grep (2)

मैं अपने अपाचे लॉग से विशिष्ट समय सीमा में अनुरोधों की राशि प्राप्त करने की कोशिश कर रहा हूं हालांकि, हालांकि यह बहुत आसान था, लेकिन जब भी मैंने 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 से अनुपलब्ध है जो पैटर्न से मेल खाता है।

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


आप 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


जैसा कि टिप्पणियों में बताया गया है, आप कई अभिव्यक्तियों के लिए खोज रहे हैं, और शुरू के पहले मैच से लेकर अंत तक के पहले मैच तक सभी लाइनों को मैच करेंगे। अपनी खुद की भाषा के रूप में, 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