मैं उन पंक्तियों के लिए एक निर्देशिका कैसे प्राप्त कर सकता हूं जिनमें "फू" शामिल हैं, लेकिन केवल तब मिलते हैं जब अगली पंक्ति में "बार" भी होता है?
मैं उन पंक्तियों के लिए एक निर्देशिका कैसे प्राप्त कर सकता हूं जिनमें "फू" शामिल हैं, लेकिन केवल तब मिलते हैं जब अगली पंक्ति में "बार" भी होता है?
जवाबों:
ग्रीप स्वयं इसका समर्थन नहीं करता है, इसके बजाय 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
)