Grep regex स्ट्रिंग युक्त नहीं है


181

मैं grepएक syslog फ़ाइल के खिलाफ जांच करने के लिए रेगेक्स पैटर्न की एक सूची दे रहा हूं । वे आमतौर पर एक आईपी पते और लॉग प्रविष्टि से मेल खाते हैं;

grep "1\.2\.3\.4.*Has exploded" syslog.log

यह सिर्फ एक पैटर्न की सूची है जैसे "1\.2\.3\.4.*Has exploded"मैं जिस हिस्से से गुजर रहा हूं, एक लूप में, इसलिए मैं उदाहरण के लिए "-v" पास नहीं कर सकता।

मैं उपरोक्त उलटा करने की कोशिश कर रहा हूं, एक निश्चित आईपी पते और त्रुटि के साथ एक मिलान रेखाएं नहीं है इसलिए "! 1.2.3.4। * विस्फोट हो गया है" 1.2.3.4 के अलावा किसी भी चीज के लिए syslog लाइनों से मेल खाएगा जो मुझे बता रहा है कि यह विस्फोट हुआ है। । मुझे मेल नहीं करने के लिए एक आईपी शामिल करने में सक्षम होना चाहिए।

मैंने StackOverflor पर इसी तरह के विभिन्न पोस्ट देखे हैं, हालांकि वे रेगेक्स पैटर्न का उपयोग करते हैं जो मुझे काम करने के लिए नहीं मिल सकता है grep। किसी को भी grepकृपया के लिए एक काम कर उदाहरण प्रदान कर सकते हैं ?

अद्यतन: यह इस तरह से एक स्क्रिप्ट में हो रहा है;

patterns[1]="1\.2\.3\.4.*Has exploded"
patterns[2]="5\.6\.7\.8.*Has died"
patterns[3]="\!9\.10\.11\.12.*Has exploded"

for i in {1..3}
do
 grep "${patterns[$i]}" logfile.log
done

क्या आपका मतलब है कि आप कभी-कभी एक पैटर्न से मेल खाना चाहते हैं, लेकिन दूसरी बार एक निश्चित पैटर्न को छोड़कर सब कुछ मैच करना चाहते हैं ? (यह एक अजीब आवश्यकता की तरह लगता है, लेकिन जो भी हो)। उस मामले में, आप पैटर्न की दो अलग-अलग सूचियों पर पुनरावृति क्यों नहीं करते हैं?
बीरबजाय

वैसे मुझे रेगेक्स के बारे में बहुत जानकारी नहीं है; मैं "हैश एक्सप्लोडेड" के लिए grep नहीं करना चाहता, क्योंकि मैं हर लॉगिंग डिवाइस के बारे में यह नहीं जानना चाहता, तो क्या मैं किसी भी तरह "has विस्फोट" और 9.10.11.12 के लिए एक बयान में grep कर सकता हूं?
jwbensley

यदि आप पूरी तरह से इसे एक बयान में करना चाहते हैं, तो निगेटिव लुकबाइंड जाने का रास्ता है, जैसा कि नील सुझाव देता है। मेरी टिप्पणी वहाँ देखें।
बीरबजय

@Neil के उत्तर के अनुसार, PCRE- शैली रेगेक्स मिलान और एक नकारात्मक लुकहेड अभिकथन का उपयोग करें: PCRE में patterns[3]="\!9\.10\.11\.12.*Has exploded"परिवर्तन patterns[3]="(?<!9\.10\.11\.12).*Has exploded"और grep "${patterns[$i]}" logfile.logपरिवर्तन grep -P "${patterns[$i]}" logfile.logडिफ़ॉल्ट रूप से अधिक मेटाचैकर को मानता है, इसलिए कुछ मिलानों को अन्य मिलान अभिव्यक्तियों से हटाने की आवश्यकता हो सकती है।
कोडेक्स 24

जवाबों:


340

grepमेल खाता है, grep -vउलटा करता है। यदि आपको "A से मेल खाना है, लेकिन B से नहीं" है, तो आप आमतौर पर पाइप का उपयोग करते हैं:

grep "${PATT}" file | grep -v "${NOTPATT}"

यह एक लूप के बीच में जा रहा है जैसा कि मैंने उल्लेख किया है और मैं सिर्फ इसलिए पास कर रहा हूं ताकि मुझे बताए अनुसार "-v" का उपयोग न कर सकूं। मैं सिर्फ PATTERNs की सूची को गोल कर रहा हूं और grep को पास कर रहा हूं।
jwbensley

1
आप वास्तव में उपयोग -vकर सकते हैं और आप इसे लूप में उपयोग कर सकते हैं। शायद आपको अपनी सीमाओं के बारे में अधिक विशिष्ट होने की आवश्यकता है, या शायद आपको इस बारे में गलत धारणा है कि आपकी स्क्रिप्ट को कैसे काम करना चाहिए। कुछ कोड पोस्ट करने का प्रयास करें।
बियरबजाय

धन्यवाद बीयरबजय, मैंने कुछ संदर्भ देने के लिए मूल पोस्ट पर छपे एक कोड को जोड़ा है। क्या आप देखते हैं कि अब मेरा क्या मतलब है?
jwbensley

यह उत्तर पूरी तरह से सही नहीं है, लेकिन आप बहुत अधिक बीयरबजाय लिख रहे थे, मुझे लूप को पुनर्विचार करने और अंत में उपयोग करने की आवश्यकता थी। सूचक के लिए धन्यवाद;)
jwbensley

1
लेकिन क्या होगा अगर A, B से बना है? दूसरे शब्दों में, क्या मैं के साथ लाइनों मिलान करना चाहते हैं कोई एक और एबी के साथ लाइनों? एक पाइप काम नहीं करेगा।
पवामोय

15
(?<!1\.2\.3\.4).*Has exploded

नेगेटिव लुकबाइंड (पर्ल रेगुलर एक्सप्रेशन) के लिए आपको -P के साथ इसे चलाने की आवश्यकता है, इसलिए कमांड है:

grep -P '(?<!1\.2\.3\.4).*Has exploded' test.log

इसे इस्तेमाल करे। यह लाइन को अनदेखा करने के लिए निगेटिव लुकबाइंड का उपयोग करता है अगर यह पहले से ही हो 1.2.3.4। उम्मीद है की वो मदद करदे!


1
मुझे पूरा यकीन है कि grepयह दिखावे का समर्थन नहीं करता है। जब तक आप ग्नू grepका उपयोग नहीं कर रहे हैं और --Pइसे एक पीसीआरई इंजन का उपयोग करने के लिए पैरामीटर का उपयोग करते हैं।
टिम पीटरज़

नहीं, grep रेगेक्स के इस प्रकार का समर्थन नहीं करता है; $ grep -P (? <! 1! 2 \ .3 \ .4) test.log -bash: अप्रत्याशित टोकन के पास सिंटैक्स त्रुटि `('
jwbensley

यदि आपको शेल द्वारा व्याख्या किए गए वर्ण हैं, तो आपको रेक्स को उद्धृत करने की आवश्यकता होगी।
बियरबजाय

सही उद्धरण: grep -P '(?<!1\.2\.3\.4) Has exploded' test.logध्यान दें कि लुकबाइंड केवल वर्णों पर काम करता है जो अभिव्यक्ति के मिलान भाग से पहले होता है, इसलिए यदि पता और संदेश के बीच अन्य चीजें हैं, जैसे 1.2.3.4 FOO Has exploded, यह काम नहीं करेगा।
बीरबजय

@ टिमपिट्ज़र, बहुत चौकस। मैं इसे प्रश्न में जोड़ दूंगा। इसके अलावा, कृपया ध्यान दें कि .*उसके उदाहरण के बाद से नकारात्मक लुकअप के बाद भी है, मुझे लगता है कि बीच में कोई अन्य पाठ हो सकता है।
नील

2
patterns[1]="1\.2\.3\.4.*Has exploded"
patterns[2]="5\.6\.7\.8.*Has died"
patterns[3]="\!9\.10\.11\.12.*Has exploded"

for i in {1..3}
 do
grep "${patterns[$i]}" logfile.log
done

जैसा होना चाहिए वैसा ही होना चाहिए

egrep "(1\.2\.3\.4.*Has exploded|5\.6\.7\.8.*Has died)" logfile.log | egrep -v "9\.10\.11\.12.*Has exploded"    
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.