次のログファイルがあります。
Event
Process 1
Process 2
End event success
Event
Process 1
Process 3
End event error
Event
Process 1
Process 5
End event success
Event
Process 1
Process 7
End event success
Event
Process 2
Process 4
End event error
次のエラーイベントを維持したいと思います。
Event
Process 1
Process 3
End event error
Event
Process 2
Process 4
End event error
試してみましたcat Event.log | awk '/Event/,/End event error/'
が、好きなようにはなりませんでした。
答え1
これは働きます:
awk '/^Event/{n=1} {lines[n++]=$0} /^End event error/{for(i=1;i<n;++i) print lines[i]}' Event.log
説明:「イベント」以降のすべての行を配列に保存し、「イベント終了エラー」が発生した場合に印刷します。
答え2
sed
抽出したくないすべての項目を削除するには、次の手順を実行します。
$ sed '/^Event$/,/^End event success$/d' file
Event
Process 1
Process 3
End event error
Event
Process 2
Process 4
End event error
答え3
$ perl -l -n -e 'BEGIN { $/ = "\nEvent" };
print "Event$_" if /End event error/' input.log
Event
Process 1
Process 3
End event error
Event
Process 2
Process 4
End event error
\nEvent
レコード区切り記号()として使用され、$/
「終了イベントエラー」を含むレコードを印刷します。
注:Perlでは、レコード区切り文字は大文字と小文字を区別する固定文字列です(つまり、正規表現ではありません)。
各レコード間に空白行が必要な場合(段落で後処理しやすいように)、印刷ステートメントをに変更しますprint "\nEvent$_" if ...
。
答え4
使用幸せ(以前のPerl_6)
~$ raku -e 'for lines.join("\n").split(/ \n <?before Event >/) { .put if .words[*-1] eq "error" };' file
#OR
~$ raku -e '.put if .words[*-1] eq "error" for lines.join("\n").split: / \n <?before Event >/;' file
RakuはPerlファミリーのプログラミング言語です。単に、
- Auto-chomped
lines
は読み込まれ、\n
改行文字に関連付けられます。出力の末尾に改行を追加することに気にしない場合は、slurp
ここで代わりに使用できます。lines.join("\n")
\n
- データは改行文字が挿入された既存のレコードに保存されます
split
(前方予測)。\n
<?before Event>
- つまり、スペースで区切られた最後の単語が「error」として記録されます
put
。if words[*-1] eq "error"
[*-1]
[注:次のコマンドを使用すると、レコードのどこからでも大文字と小文字を区別しない「エラー」のあるレコードを返すことができますif m:i/error/
。
入力例:
Event
Process 1
Process 2
End event success
Event
Process 1
Process 3
End event error
Event
Process 1
Process 5
End event success
Event
Process 1
Process 7
End event success
Event
Process 2
Process 4
End event error
出力例:
Event
Process 1
Process 3
End event error
Event
Process 2
Process 4
End event error
レコードが正しく分割されていることを確認するために、中間項目を表示できます(if
上記の条件を削除して追加raku
)。
~$ raku -e '.raku.put for lines.join("\n").split: / \n <?before Event>/;' file
"Event\nProcess 1\nProcess 2\nEnd event success"
"Event\nProcess 1\nProcess 3\nEnd event error"
"Event\nProcess 1\nProcess 5\nEnd event success"
"Event\nProcess 1\nProcess 7\nEnd event success"
"Event\nProcess 2\nProcess 4\nEnd event error"
面白いので、タブにjoin
/を入力すると非常に簡単な出力が得られます(入力ファイルにタブがないと仮定)。split
\t
~$ raku -e '.put if .words[*-1] eq "error" for lines.join("\t").split: / \t <?before Event>/;' file
Event Process 1 Process 3 End event error
Event Process 2 Process 4 End event error