2012-06-10 8 views
8

में एक मैच के बाद अगला WORD प्राप्त करने के लिए grep का उपयोग करना, मैं अपने सर्वर लॉग से "प्राप्त करें" प्राप्त करना चाहता हूं।प्रत्येक लाइन

उदाहरण के लिए, इस सर्वर लॉग

1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:32:27] code 404, message File not fo$ 
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:32:27] "GET /hello HTTP/1.1" 404 - 
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:41:57] code 404, message File not fo$ 
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:41:57] "GET /ss HTTP/1.1" 404 - 

जब मैं सरल ग्रेप या awk के साथ प्रयास करें,

Adi:~ adi$ awk '/GET/, /HTTP/' serverlogs.txt 

इसे बाहर देता है

1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:32:27] "GET /hello HTTP/1.1" 404 - 
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:41:57] "GET /ss HTTP/1.1" 404 - 

मैं सिर्फ प्रदर्शित करना चाहते हैं : हैलो और एसएस

क्या ऐसा कोई तरीका हो सकता है?

उत्तर

8

आप यह सोचते हैं, तो आप पर्ल शैली regex का उपयोग कर सकते हैं एक सकारात्मक lookbehind करने के लिए जीएनयू ग्रेप है:

grep -oP '(?<=GET\s/)\w+' file 

आप जीएनयू ग्रेप की जरूरत नहीं है, तो मैं सिर्फ एसईडी का उपयोग कर सलाह देंगे:

sed -n '/^.*GET[[:space:]]\{1,\}\/\([-_[:alnum:]]\{1,\}\).*$/s//\1/p' file 

आप (जो अजीब यदि आप जीएनयू ग्रेप नहीं है, लेकिन gnu sed की क्या ज़रूरत है होगा) जीएनयू sed हैं तो आप हैं, तो है कि बहुत सरल किया जा सकता:

sed -n '/^.*GET\s\+\/\(\w\+\).*$/s//\1/p' file 

नीचे की रेखा है, आपको निश्चित रूप से इसे पूरा करने के लिए पाइप की आवश्यकता नहीं है। grep या sed अकेले पर्याप्त होगा।

+0

बहुत बढ़िया। अच्छी तरह से काम!! छोटा और सरल –

5

इस मामले में लॉग फ़ाइल की एक ज्ञात संरचना है, इसलिए 7 वें कॉलम को खींचने के लिए cut का उपयोग करना एक विकल्प है (फ़ील्ड्स डिफ़ॉल्ट रूप से टैब द्वारा इंगित किए जाते हैं)।

grep GET log.txt | cut -f 7 
+0

अभी भी पूरी लाइन दिखा रहा है। 1.0.0.127.in-addr.arpa - - [10/जून/2012 15:32:27] "प्राप्त करें/हैलो HTTP/1.1" 404 - 1.0.0.127.in-addr.arpa - - [10/जून/2012 15:41:57] "HTTP/1.1 प्राप्त करें" 404 - –

+0

हम्म, क्या यह स्थान या टैब अलग है? यदि स्पेस, कॉलम डिलीमीटर के रूप में स्पेस निर्दिष्ट करने के लिए कट के साथ '-d ''' का उपयोग करें। –

+0

** - डी '** पैरामीटर के साथ बढ़िया काम करता है। –

1

एक जटिल नियमित अभिव्यक्ति के बजाय पाइपलाइन का उपयोग करना अक्सर आसान होता है।

fgrep GET /tmp/foo | 
    egrep -o 'GET (.*) HTTP' | 
    sed -r 's/^GET \/(.+) HTTP/\1/' 

इस पाइपलाइन परिणाम मिलते हैं:: यह डेटा आपके द्वारा दी गई पर काम करता है

hello 
ss 

वहाँ निश्चित रूप से कर रहे हैं अन्य तरीकों से काम करवाने के लिए, लेकिन यह साफ़ तौर पर प्रदान की जाती कोष पर काम करता है।

2

एक पाइप उपयोग करें यदि आप ग्रेप का उपयोग करें:

grep -o /he.* log.txt | grep -o [^/].* 
grep -o /ss log.txt | grep -o [^/].* 

[^ /] पत्र निकालने^ग्रेप उत्पादन से प्रतीक के बाद

0
gawk '{match($7,/\/(\w+)/,a);} length(a[1]){print a[1]}' log.txt 
hello 
ss 

यदि आपके पास gawk तो आदेश ऊपर का उपयोग करेगा मतलब है match फ़ंक्शन का उपयोग करके वांछित मान का चयन करने और इसे एरे a पर संग्रहीत करने के लिए फ़ंक्शन का चयन करें।

0

मैं यह करने के कोशिश कर रहा था और इस लिंक भर में आया:, मिलान लाइनों को खोजने के लिए उपयोग ग्रेप तो awk का उपयोग पैटर्न खोजने के लिए और अगले क्षेत्र प्रिंट: https://www.unix.com/shell-programming-and-scripting/153101-print-next-word-after-found-pattern.html

सारांश

grep pattern logfile | \ 
    awk '{for(i=1; i<=NF; i++) if($i~/pattern/) print $(i+1)}' 

यदि आप अद्वितीय घटनाओं को जानना चाहते हैं:

grep pattern logfile | \ 
    awk '{for(i=1; i<=NF; i++) if($i~/pattern/) print $(i+1)}' | \ 
    sort | \ 
    uniq -c 
संबंधित मुद्दे