Grep 记录并获取日志分隔符之间的文本

use*_*755 4 grep subversion

有没有办法grep记录日志并在日志条目分隔符之间查找文本?我们的日志文件用字符“ -------”分隔行条目,所以当我搜索文本词时,我想要日志中分隔符前后的所有行。

示例日志

------------------------------------------------------------------------

    r132279 | USERID | 2014-04-30 12:59:09 -0700 (Wed, 30 Apr 2014) | 3 lines
    Removed unused "Calculated Fields" column entry.
    Jira ID: JIRA-977

------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

在上面我会 Grep 这个词 Fields 但想要 " ----" 行之间的所有行

ste*_*ver 6

如果您知道记录有多大,那么您可以在匹配行之前 ( -B) 和之后 ( -A)输出额外的上下文行,例如

grep -A2 -B2 'Fields' sample.log
Run Code Online (Sandbox Code Playgroud)

或匹配行前后的上下文

grep -C3 'Fields' sample.log
Run Code Online (Sandbox Code Playgroud)

据我所知,在 GNU grep 中进行真正的多行匹配(而不是单行匹配加上上下文)的唯一方法是使用-P带有-z标志的 PCRE 正则表达式模式 ( )来防止换行符中断。例如,你可以尝试

grep -zPo '(\n-+\n)\K(.|\n)+?Fields(.|\n)+?(?=\n-+\n)'
Run Code Online (Sandbox Code Playgroud)

它对Fields由任何字符或换行符包围的字符串进行非贪婪匹配,前提是它由换行符-连字符-换行符分隔符预订。pcregrep 中的等效表达式是

pcregrep -Mo '(\n-+\n)\K(.|\n)+?Fields(.|\n)+?(?=\n-+\n)'
Run Code Online (Sandbox Code Playgroud)


这种记录结构数据的另一种选择是 awk:特别是,GNU awk 允许将正则表达式用于内部记录分隔符RS,例如

$ gawk -vRS='\n-+\n' '/Fields/ {print}' sample.log

r132279 | USERID | 2014-04-30 12:59:09 -0700 (Wed, 30 Apr 2014) | 3 lines

Removed unused "Calculated Fields" column entry.

Jira ID: JIRA-977
Run Code Online (Sandbox Code Playgroud)