与linux匹配的相对日志文件?

与linux匹配的相对日志文件?

我已经知道如何使用grepawk匹配日志文件中的某些内容,但是有没有办法执行以下操作?

  1. 匹配文件中的特定行...并将其包含在结果中。
  2. 从文件中 (1.) 的匹配行开始,向上查找,直到匹配第二个字符串,并将其以及其间的所有行包含在结果中。
  3. 然后,使用第三个匹配项,从匹配项 (1.) 开始搜索,匹配第三个字符串并将其以及结果之间的所有行包含在内。

这样,如果正在搜索的内容位于 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]

上述假设:

  1. 您要搜索的 3 个字符串始终出现在彼此不同的行上。
  2. 您总是希望从最后一个 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]

相关内容