複数の行で複数のパターンをgrepするにはどうすればよいですか?


19

正確に言うと

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

「開始」から「終了」までのブロック全体を抽出したい。

awkを使用すると、次のようにできますawk '/begin/,/end/' text

grepの使用方法


回答:


14

2016年11月18日に更新(grepの動作が変更されたため、-Pパラメーターを指定したgrepは、[Ubuntu 16.04でカーネルv:4.4.0-21-generic]をサポート^および$アンカーしなくなりました)(間違った(非)修正

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

注:他のコマンドについては、 '^'& '$'アンカーを改行アンカーに置き換えてください'\n' ______________________________

grepコマンドを使用:

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

結果にパターン「begin」と「end」を含めたくない場合は、LookbehindおよびLookaheadをサポートしたgrepを使用してください。

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

また\K、Lookbehindアサーションの代わりにnotify を使用できます。

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)ドットが改行文字と一致することを許可するようにgrepに指示します。
[\s\S]空白または空白以外の文字に一致します。

そして、「begin」と「end」を含まない出力は次のとおりです。

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

ここですべてのコマンドの完全なテストを参照してください-Pパラメーターを使用したgrepの動作が変更されたため、古い

注意:

^行の始まりを指し、行$の終わりを指します。これらは、「begin」と「end」の前後に追加され、それらが一列に並んでいる場合、それらを一致させます。
2つのコマンドでは、コマンドの出力でコマンド名を置き換えることができる$「コマンド置換」($(command))も使用しているため、エスケープしました。

man 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を変更して、begin行に存在する文字を出力grep -Pzo "(?<=begin\n)(.|\n)*(?=\nend)" fileしないようにし\nます。
アビナッシュラジ14年

DOTALL修飾子を使用して、改行文字にも一致するようにドットを作成しますgrep -Pzo "(?s)begin.*?end" file
Avinash Raj 14年

あるいは単に、grep -Pzo "begin[\s\S]*?end" file
のAvinashラジ

1
解決策は機能しません。エラーが生成されます。エラー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

grepperl構文(-P)をサポートしていない場合、行を結合し、パターンに一致させてから、以下のように再度行を展開できます。

$ tr '\n' , < foo.txt | grep -o "begin.*end" | tr , '\n'
begin
Some text goes here.
end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.