如何 grep/awk/sed 查找日志中的文本并显示包含该文本的块?

如何 grep/awk/sed 查找日志中的文本并显示包含该文本的块?

我正在寻找与以下内容非常相似的东西

日志如下所示:

[09:44:22] [main] ERROR [url/location] - A ONE LINE ERROR
[09:44:22] [main] ERROR [url/location] - Another ERROR 
[09:44:22] [main] SOMETHING DIFFERENT
[09:44:22] [main] SOMETHING DIFFERENT AGAIN
[09:44:22] [main] WARN [url/location] - ANOTHER ONE LINE WARN

一行接着一行,行之间没有空行,但当有特定片段的更多信息可用时,偶尔会有缩进。

我希望能够提取包含的每一行(理想情况下作为可以提取And/Or 、等ERROR的脚本)并根据参数显示它们。它将使筛选日志以查找失败等变得更加容易。ERRORFAILWARN

答案1

GNU grep能够非常简单地做到这一点。从man grep

两个正则表达式可以通过中缀运算符 | 连接;生成的正则表达式与匹配任一子表达式的任何字符串相匹配。

grep "ERROR\|FAIL\|WARN" /path/to/example.log

egrep消除了转义符号的需要|

egrep "ERROR|FAIL|WARN" /path/to/example.log

答案2

我想你的日志文件看起来像这样?

示例.log:

[09:44:22] [main] ERROR [url/location] - A ONE LINE ERROR
[09:44:22] [main] ERROR [url/location] - A MULTI LINE ERROR 
    with whitepace indention
[09:44:22] [main] ERROR [url/location] - A MULTI LINE ERROR 
       with tab indention
[09:44:22] [main] SOMETHING DIFFERENT
[09:44:22] [main] SOMETHING DIFFERENT
       with tab indention
[09:44:22] [main] WARN [url/location] - ANOTHER ONE LINE WARN

诚然,这在 Perl 中不是一句简单的话,但它应该可以完成这项工作:

日志筛选器.pl:

#!/usr/bin/perl
use warnings;
use strict;

my $buffer="";

while(my $line= <>){
  chomp $line;
  if($line=~/ERROR|INFO|WARN/){
    print "$buffer\n" if $buffer;
    $buffer = $line;
  }
  elsif($line=~/^\s+(.*)$/){
    $buffer .= $1 if $buffer;
  }
  else{
    if($buffer){
      print "$buffer\n";
      $buffer ="";
    }
  }
}

print "$buffer\n";

像这样称呼它:

perl logsifter.pl < example.log
 [09:44:22] [main] ERROR [url/location] - A ONE LINE ERROR
 [09:44:22] [main] ERROR [url/location] - A MULTI LINE ERROR with whitepace indention
 [09:44:22] [main] ERROR [url/location] - A MULTI LINE ERROR with tab indention
 [09:44:22] [main] WARN [url/location] - ANOTHER ONE LINE WARN

答案3

现在,您的数据格式已经建立,答案变得简单得多:grep是为

用于grep '<PATTERN>' <dataFile>

哪里<PATTERN>SearchWORD1SearchW1\|SearchW2

当我和@murphy 对数据格式仍然有错误的假设时,写下了下面的答案:

这是一个单行 awk 程序,仅搜索错误:

awk '/ERROR/{a=1;print} /^ / || /^\t/ {if (a) print;next} !/ERROR/ {a=0}'

您可以将其变成带有参数的灵活 shell 函数:

searchlog(){ awk -f <( echo "
/$1/{a=1;print}
/^ /||/^\t/{if (a) print;next}
! /$1/{a=0}
"); }

运行它作为LogData_generated_by_program | searchlog <PATTERN>, 或searchlog <PATTERN> < File_containing_Log_Data

对于其他回答者“猜测”的示例数据格式,结果是:

$ searchlog ERROR < /tmp/exampleData
[09:44:22] [main] ERROR [url/location] - A ONE LINE ERROR
[09:44:22] [main] ERROR [url/location] - A MULTI LINE ERROR 
    with whitepace indention
[09:44:22] [main] ERROR [url/location] - A MULTI LINE ERROR 
       with tab indention

相关内容