web-dev-qa-db-ja.com

コンテキストの後にgrepを「次の空白行まで」に設定するにはどうすればよいですか?

Grepを使用すると、コンテキストを固定の行数に設定する方法がわかります。 after-contextを「次の空白行まで」に設定するなど、任意の文字列条件に基づいてコンテキストを表示することは可能ですか?

または、おそらく他のツールの組み合わせ?

基本的に、ログファイル内の文字列を検索したいがイベント全体を表示したい「イベント」を分離する空行で、連続した行のログファイルがあります。

32
pixelearth

sedが必要なようです:

sed -n '/pattern/,/^$/p' file

デフォルトでは印刷しません(-n)。 /pattern/から空の行/^$/まで一致する行の場合、印刷します。

31

簡単な解決策は次のとおりです。

awk '/pattern/' RS= input-file

RSを空の文字列に設定すると、awkは空白行をレコード区切り文字として扱い、単純なルール/pattern/を指定すると、awkはパターンに一致するすべてのレコードを出力します。これには、拡張正規表現を使用できます。

21
William Pursell

読みやすいように複数の行に分けられた(テスト済み)awkソリューションを次に示します。

awk '/pattern/ {do_print=1}
     do_print==1 {print}  
     NF==0 {do_print=0}' input_file

このスクリプトは空白行も出力するため、一致するさまざまなブロックを視覚的に簡単に分離できます。空白行が必要ない場合は、do_print==1 {print}NF==0 {do_print=0}の2行を入れ替えます

説明:

  • awkawkツールを呼び出します-入力を一度に1行ずつ順次評価します。
  • '...'.:単一引用符で囲まれたものはすべて、指示としてawkに渡されます。この場合、各行で引用された指示を実行します。
  • /pattern/ {do_print=1}:行に「pattern」が含まれる場合は常に、do_printフラグをオンにします
  • do_print==1 {print}do_printフラグがオンに設定されている場合、現在の行を出力します。
  • NF==0 {do_print=0}:NFはフィールド数を表します。 awkは、デフォルトで各行をスペースとタブで区切り、行をフィールドに分割します。この場合、空白行にはフィールドがありません。したがって、do_printの行が表示されたら印刷を停止するためにNF == 0フラグをオフにします
8
sampson-chen

個人的には、@ William Pursellからの回答が好きです。これは、beforeコンテキストが役立つことが多いためです(たとえば、iniファイルの内容をgrepするとき)。実際にawkでアフターコンテキストのみが必要な場合、これを行うことができます。

$ cat demo.ini 
[foo]
aaa = 1
bbb = 2
ccc = 3

[bar]
eee = 8
fff = 0
ggg = 1

[baz]
xxx = 1
yyy = 0
zzz = 2
$ awk '/bar/,/^$/' demo.ini 
[bar]
eee = 8
fff = 0
ggg = 1

$ awk '/fff/,/^$/' demo.ini 
fff = 0
ggg = 1

$

RS=バージョンと比較してください:

$ awk '/bar/' RS= demo.ini 
[bar]
eee = 8
fff = 0
ggg = 1
$ awk '/fff/' RS= demo.ini 
[bar]
eee = 8
fff = 0
ggg = 1
0
htaccess