로그에서 텍스트를 찾고 해당 텍스트가 포함된 블록을 표시하려면 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

줄은 줄을 따라가며, 줄 사이에 빈 줄이 없지만 특정 조각에 대한 추가 정보를 사용할 수 있는 경우 가끔씩 들여쓰기가 됩니다.

ERROR포함된 각 줄을 추출하고(이상적으로는 And/Or 등을 추출할 수 있는 스크립트 로) 매개변수에 따라 표시할 수 있기를 원합니다 . 오류 등을 찾기 위해 로그를 살펴보는 것이 더 쉬워집니다.ERRORFAILWARN

답변1

GNU grep아주 간단하게 이 작업을 수행할 수 있습니다. 에서 man grep:

두 개의 정규식은 중위 연산자 |로 연결될 수 있습니다. 결과 정규식은 두 하위 표현식과 일치하는 모든 문자열과 일치합니다.

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

egrep기호를 이스케이프할 필요가 없습니다 |.

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

답변2

로그 파일이 다음과 같을 것 같은데요?

예.로그:

[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에서 간단한 설명은 아니지만 작업을 수행해야 합니다.

로그 filter.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>입니까 SearchWORD1?SearchW1\|SearchW2

@murphy와 내가 여전히 데이터 형식에 대해 잘못된 가정을 갖고 있을 때 다음 답변이 작성되었습니다.

이것은 검색만 수행하는 한 줄의 awk 프로그램입니다.실수:

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

이를 매개변수를 사용하여 유연한 쉘 함수로 전환할 수 있습니다.

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

관련 정보