मैं कई लाइनों पर कई पैटर्न के लिए कैसे तैयार हो सकता हूं?


19

सटीक होना

Some text
begin
Some text goes here.
end
Some more text

और मैं "ब्लॉक" से शुरू होने वाले पूरे ब्लॉक को "अंत" तक निकालना चाहता हूं।

जाग के साथ हम ऐसा कर सकते हैं awk '/begin/,/end/' text

ग्रीप के साथ कैसे करें?


जवाबों:


14

अपडेट किया गया 18-नवंबर -2016 (क्योंकि grep व्यवहार बदल गया है: grep--P पैरामीटर के साथ अब समर्थन नहीं करता है ^और $एंकर [Ubuntu 16.04 पर कर्नेल v: 4.4.0-21-जेनेरिक के साथ]) ( गलत (गैर) फिक्स )

$ grep -Pzo "begin(.|\n)*\nend" file
begin
Some text goes here.  
end

नोट: अन्य आदेशों के लिए बस '^' और '$' एंकरों को नई-लाइन एंकर '\n' ______________________________ से बदलें

Grep कमांड के साथ:

grep -Pzo "^begin\$(.|\n)*^end$" file

यदि आप चाहते हैं कि परिणाम में "प्रारंभ" और "अंत" पैटर्न शामिल न हों, तो लुकबाइंड और लुकहेड समर्थन के साथ grep का उपयोग करें।

grep -Pzo "(?<=^begin$\n)(.|\n)*(?=\n^end$)" file

इसके अलावा, आप \Kलुकअप एशोसिएशन के बजाय सूचना का उपयोग कर सकते हैं ।

grep -Pzo "^begin$\n\K(.|\n)*(?=\n^end$)" file

\Kविकल्प पैटर्न मिलान से पहले सब कुछ अनदेखा करें और पैटर्न को ही अनदेखा करें।
\nआउटपुट से खाली लाइनों को प्रिंट करने से बचने के लिए उपयोग किया जाता है।

या जैसा कि @AvinashRaj का सुझाव है कि निम्नलिखित के रूप में सरल आसान grep हैं:

grep -Pzo "(?s)^begin$.*?^end$" file

grep -Pzo "^begin\$[\s\S]*?^end$" file

(?s)जीआरईपी से कहता है कि डॉट को नईलाइन वर्णों का मिलान करने की अनुमति दें।
[\s\S]किसी भी वर्ण से मेल खाता है जो या तो व्हाट्सएप या गैर-व्हाट्सएप है।

और "आरंभ" और "अंत" को शामिल किए बिना उनका आउटपुट निम्नानुसार है:

grep -Pzo "^begin$\n\K[\s\S]*?(?=\n^end$)" file # or grep -Pzo "(?<=^begin$\n)[\s\S]*?(?=\n^end$)"

grep -Pzo "(?s)(?<=^begin$\n).*?(?=\n^end$)" file

सभी आदेशों की पूरी परीक्षा यहाँ देखें ( पीए पैरामीटर के साथ grep व्यवहार के रूप में दिनांकित )

ध्यान दें:

^एक पंक्ति की शुरुआत $बिंदु और एक पंक्ति के अंत बिंदु। अगर वे एक पंक्ति में अकेले हैं, तो उन्हें "शुरू" और "अंत" के आसपास जोड़ा जाता है।
दो आदेशों में मैं बच गया $क्योंकि यह "कमांड सबस्टीट्यूशन" ( $(command)) के लिए भी उपयोग करता है जो कमांड के आउटपुट को कमांड नाम को बदलने की अनुमति देता है।

आदमी से grep:

-o, --only-matching
      Print only the matched (non-empty) parts of a matching line,
      with each such part on a separate output line.

-P, --perl-regexp
      Interpret PATTERN as a Perl compatible regular expression (PCRE)

-z, --null-data
      Treat the input as a set of lines, each terminated by a zero byte (the ASCII 
      NUL character) instead of a newline. Like the -Z or --null option, this option 
      can be used with commands like sort -z to process arbitrary file names.

अपने grep को बदलना शुरू करें जो लाइन पर मौजूद चरित्र grep -Pzo "(?<=begin\n)(.|\n)*(?=\nend)" fileको प्रिंट नहीं करना चाहते हैं \n
अविनाश राज

डॉटलाइन संशोधक का प्रयोग डॉट को मैच करने के लिए करें यहां तक ​​कि न्यूलाइन चार्ट से भी मिलान करने के लिएgrep -Pzo "(?s)begin.*?end" file
अविनाश राज

या बस,grep -Pzo "begin[\s\S]*?end" file
अविनाश राज

1
Siólution काम नहीं करता है। यह एक त्रुटि पैदा करता है: त्रुटि grep: ein nicht geschütztes ^ oder $ wird mit -Pz nicht unterstütztका अनुवाद कुछ इस प्रकार है:grep: a not protected ^ or $ is not supported with -Pz
musbach

1
हां, मुझे पता है, यह आपके जवाब में है। मुझे यकीन है कि जब आप इसे पोस्ट करते हैं तो यह काम करता है, लेकिन आज फिर से कोशिश करें। grepलगता है व्यवहार बदल गया है।
टेराडॉन

2

यदि आपका grepपर्ल पर्ल सिंटैक्स ( -P) का समर्थन नहीं करता है , तो आप लाइनों से जुड़ने की कोशिश कर सकते हैं, पैटर्न से मेल खा सकते हैं, फिर नीचे फिर से लाइनों का विस्तार कर सकते हैं:

$ tr '\n' , < foo.txt | grep -o "begin.*end" | tr , '\n'
begin
Some text goes here.
end
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.