grep
ログファイルの内容を使用または一致させる方法は既にわかっていますが、awk
次のことを行う方法はありますか?
- ファイルの特定の行を一致させ、結果に含めます。
- ファイル(1.)の一致する行から始まり、2番目の文字列が一致するまで上向きに検索し、その文字列とその間のすべての行を結果に含めます。
- 次に、3番目の一致を使用して一致(1.)から始めて3番目の文字列を一致させ、その文字列と結果の間のすべての行を含めて検索します。
これにより、検索したいコンテンツがBEGINNINGおよびENDコンテキストにある場合、検索したいコンテンツが発生したコンテキストのみを検索できます。ログファイルは次のとおりです。
<several-1000-lines>
...[BEGINX]
some log a
<several-1000-lines>
...[First-string-i-search-for]
<several-1000-lines>
some log b
...[ENDX]
<several-1000-lines>
その後、検索すると次の結果が表示されます[First-string-i-search-for]
。
...[BEGINX]
some log a
<several-1000-lines>
...[First-string-i-search-for]
<several-1000-lines>
some log b
...[ENDX]
答え1
$ cat tst.awk
BEGIN {
beg = "[BEGINX]"
mid = "[First-string-i-search-for]"
end = "[ENDX]"
}
index($0,beg) {
gotBeg = 1
gotMid = 0
buf = ""
}
gotBeg {
buf = buf $0 ORS
if ( index($0,mid) ) {
gotMid = 1
}
if ( index($0,end) ) {
if ( gotMid ) {
printf "%s", buf
}
gotBeg = 0
}
}
$ awk -f tst.awk file
...[BEGINX]
some log a
<several-1000-lines>
...[First-string-i-search-for]
<several-1000-lines>
some log b
...[ENDX]
上記の仮定は次のとおりです。
- 検索中の3つの文字列は常に異なる行に表示されます。
- いつも最後のBEGINXからその後の最初のENDXまでテストしたいと思います。
答え2
grep
PCREサポートでGNUを使用する(Perl互換正規表現):
grep -Pzo '.*\[BEGINX\](.|\n)*?\[First-string-i-search-for\](.|\n)*?\[ENDX\].*\n' infile
それは:
grep -Pzo '.*BEGINNING(.|\n)*?MIDDLE(.|\n)*?END.*\n' infile
答え3
GNU sedは範囲演算子を使用して、予約済みスペースにブロックを格納します。最後の行で、文字列がブロックにあることを確認して印刷できます。
sed -n '
/\[BEGINX]/!d
:loop
H;n
/\[ENDX]/!bloop
H;z;x
/\[First-string-i-search-for]/p
' file
範囲演算子を使用すると、,
次のように解決できます。
awk '
BEGIN { str = "[First-string-i-search-for]" }
/\[BEGINX]/, /\[ENDX]/ {a[++n]=$0}
n==1 {seen=0;next}
n && index($0,str) {seen++;next}
n && /\[ENDX]/ {flush(seen)}
function flush(flag, i) {
if (flag) for (i=1; i<=n; i++) print a[i]
n = split("", a, ":")
}
' file
...[BEGINX]
some log a
<several-1000-lines>
...[First-string-i-search-for]
<several-1000-lines>
some log b
...[ENDX]