मैं उन पंक्तियों के लिए एक निर्देशिका कैसे प्राप्त कर सकता हूं जिनमें "फू" शामिल हैं, लेकिन केवल तब मिलते हैं जब अगली पंक्ति में "बार" भी होता है?
मैं उन पंक्तियों के लिए एक निर्देशिका कैसे प्राप्त कर सकता हूं जिनमें "फू" शामिल हैं, लेकिन केवल तब मिलते हैं जब अगली पंक्ति में "बार" भी होता है?
जवाबों:
ग्रीप स्वयं इसका समर्थन नहीं करता है, इसके बजाय pcregrep का उपयोग करें:
Foo
Bar
Foo
abc
pcregrep -M "Foo\nBar" file
समझे:
Foo
Bar
Fooऔर Barइसमें पूरी लाइन शामिल होगी।
एक sedस्क्रिप्ट के साथ :
#!/bin/sed -nf
/^Foo/{
h # put the matching line in the hold buffer
n # going to nextline
/^Bar/{ # matching pattern in newline
H # add the line to the hold buffer
x # return the entire paragraph into the pattern space
p # print the pattern space
q # quit the script now
}
}
इसके प्रयेाग के लिए :
chmod +x script.sed
printf '%s\n' * | ./script.sed
printfयहाँ एक लाइन प्रत्येक पर मौजूदा निर्देशिका में सभी फ़ाइलों को प्रदर्शित करते हैं, और यह करने के लिए पारित sed।
नोट : यह वर्णानुक्रम द्वारा क्रमबद्ध किया गया है।
अधिक उपयोगी pattern spaceऔर hold space यहाँ के infos ।
grymoire.com में shellप्रोग्रामिंग के बारे में बहुत अच्छी चीजें हैं ।
h, n, H, x, p, qमतलब है? बहुत ही रोचक।
pattern space& hold space: grymoire.com/Unix/Sed.html#uh-56 या फ्रेंच में commentcamarche.net/faq/9536-sed-introduction-a-sed-part-i
grepकेवल का उपयोग करके , आप निम्नलिखित पाइप का निर्माण कर सकते हैं:
grep -A1 'Foo' input_file | grep -B1 'Bar' | grep 'Foo'
पहले grepउन सभी लाइनों को प्राप्त Fooकरेंगे जिनमें मैच के बाद की रेखा शामिल है। फिर हमें वे लाइनें मिलती हैं जिनमें Barमैच से पहले की रेखा भी होती है , और अंत में इस आउटपुट से रेखाओं को निकालते हैं जो इसमें होते हैं Foo।
EDIT: जैसा कि मैनटवर्क ने बताया है, कुछ समस्याग्रस्त मामले हैं जो देखने योग्य हैं। हालांकि एक दिलचस्प चुनौती है, grep'लाइन ओरिएंटेड फंक्शनलिटी' की वजह से , इसके साथ कोई भी समाधान 'हैक' होने की संभावना है और आप शायद किसी ऐसी चीज़ का उपयोग करने से बेहतर हैं, pcregrepजो हाथ में काम करने के लिए अधिक अनुकूल है।
find . -name '*.txt' | xargs grep -A1 'Foo' | grep -B1 'Bar'
जबकि मैं नाथन के समाधान का उपयोग करना पसंद करता हूँ pcregrep, यहाँ केवल grep का उपयोग करके समाधान है
grep -o -z -P 'Foo(.*)\n(.*)Bar' file
विकल्प स्पष्टीकरण:
-oकेवल मिलान किए गए भाग को प्रिंट करें। आवश्यक शामिल किए जाने के बाद से -zपूरी फाइल का प्रिंटआउट लिया जाएगा (जब तक कि कहीं एक \ 0 नहीं है)-z इनपुट को लाइनों के एक सेट के रूप में मानें, प्रत्येक को एक शून्य बाइट (ASCII NUL वर्ण) द्वारा एक नई रेखा के बजाय समाप्त किया जाता है।-P पर्ल रेगेक्स सिंटैक्स संपादित करें: यह संस्करण संपूर्ण मिलान वाली रेखाओं को प्रिंट करता है
grep -o -P -z '(.*)Foo(.*)\n(.*)Bar(.*)' file
-z। पूरी अभिव्यक्ति से पहले और बाद में कुछ "(। *)" यह पूरे मिलान लाइनों का उत्पादन करेगा। अब "फू" से पहले और "बार" के बाद सबस्ट्रिंग प्रदर्शित नहीं होते हैं।
Awk के साथ:
awk '/bar/ && prev != "" {print FILENAME ": " prev "\n" FILENAME ": " $0}
/foo/ {prev=$0; next}
{prev=""}' file1...
(awk limitation के बारे में सामान्य टिप्पणी: सावधान रहें कि यदि कुछ फ़ाइल नामों में "=" अक्षर हो सकते हैं, तो आपको जागने के ./filenameबजाय उन्हें पास करना होगा filename)