Tail Grep - 打印周围的行直到模式匹配

Tail Grep - 打印周围的行直到模式匹配

这是我的要求。

我正在跟踪一个日志文件并对其进行 grep。
我想获取每个 grep 结果的一些上下文。
但上下文应该是“直到匹配模式”而不是行数(这是grep -A/-B/-C提供的)。

例如
说这是我的日志..

[l]是每个日志行的前缀。另外还会有[logTypeA]or的前缀[logTypeB]

[l][logTypeA] - Log line 1
[l][logTypeB] - Log line 2 
[l][logTypeA] - Log line 3 
.... 

Random data about Log line 3
....

[l][logTypeB] - Log line 4

现在,如果我的tail命令是tail -f log_file.log | grep "[logTypeA]",我会得到一个输出

[l][logTypeA] - Log line 1
[l][logTypeA] - Log line 3 

但我需要 grep 结果的上下文信息,并且该上下文不是某些行数,而是直到匹配特定模式(在本例中为 [l])。

在这个例子中我希望我的 grep 结果是

[l][logTypeA] - Log line 1
[l][logTypeA] - Log line 3 
.... 

Random data about Log line 3
....

从这里 (如何在每个 grep 匹配之后显示行,直到其他特定匹配?),我尝试了类似的sed命令tail

tail -f log_file.log | sed '/\[logTypeA\]/,/\[l\]/p'

但这似乎不起作用。

有任何想法吗?

答案1

这是 Awk 中极其常见的模式。将相关行收集到“记录”中,收集完所有记录后,如果符合特定条件,则打印记录。

tail -f file |
awk '/\[l]/ { if (p && stored) print stored; stored = ""; p=0 }
    /\[logTypeA]/ { p=1 }
    { stored = stored (stored ? ORS : "") $0 }
    END { if (p) print stored }'

END对于永无止境的流,该条件实际上没有意义tail -f,但我将其包含在内是为了更好地衡量,并避免当您要测试的最后一条记录应该被打印时,避免令人讨厌的测试失败,但不会没有该END子句。

答案2

我最终可能会用 Perl 语句来做这件事。您可以在 sed 中完成此操作,但感觉它开始遇到 sed 的“无意的图灵完整性”部分。

Perl 一行(perl -ne这才是真正的要点)

echo  '[l] boring\nboring data\n[l] boring\n[l]interesting\ndata\ndata\n[l]boring' |  perl -ne '
    if (/\[l\].*interesting/ ) { print $_; $collect=1 ; }
    elsif (/\[l\]/) {$collect=0 }
    elsif ($collect) {print $_}'

作为参考,这是执行相同操作的 sed 单行代码。 (使用的sed的特点:来实现切换,时间来实现条件执行)。

echo  '[l] boring\nboring data\n[l] boring\n[l\]interesting\ndata\ndata\n[l]boring' |  sed -nE '/\[l\].*interesting/ {
p;
s/.*/collect/ ; x ; # store collect marker in the pattern space
b; # terminate processing
}

/\[l\]/ {
s/.*// ; x; # clear hold flag
b
}

/./ {
x;
s/collect/collect/;
T; x; p # print if we are collecting
}
'

相关内容