특정 시간 범위 내의 로그를 필터링하는 방법

특정 시간 범위 내의 로그를 필터링하는 방법

내 로그 형식은 다음과 같습니다(데모를 위해 단순화됨).

2018-04-12 14:43:00.000 ERROR hello
2018-04-12 14:44:01.000 ERROR world
2018-04-12 14:44:03.000 INFO this is a multi-line log
NOTICE THIS LINE, this line is also part of the log
2018-04-12 14:46:00.000 INFO foo

그렇다면 로그를 필터링하여 [2018-04-12 14:44:00.000, 2018-04-12 14:45:00.000)다음 출력을 생성하려면 어떻게 해야 합니까?

2018-04-12 14:44:01.000 ERROR world
2018-04-12 14:44:03.000 INFO this is a multi-line log
NOTICE THIS LINE, this line is also part of the log

답변1

그리고 awk:

awk -v 'start=2018-04-12 14:44:00.000' -v end='2018-04-12 14:45:00.000' '
   /^[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2} / {
     inrange = $0 >= start && $0 <= end
   }
   inrange' < your-file

mawkPOSIX 문자 클래스와 공백 정규식 연산자가 지원되지 않으면 작동하지 않습니다 .

답변2

특정 시간 사이에 특정 라인만 원한다면 awk그게 전부입니다. 간단한 튜토리얼 제공

먼저 원하는 경로를 찾으십시오.

cat -n logfile

그러면 줄 번호와 함께 파일 내용이 표시됩니다.

원하는 줄 번호를 인쇄하려면:

awk 'NR==2,NR==4' logfile

그러면 2행과 4행 사이의 범위가 인쇄됩니다.

두 개 이상의 줄 또는 연속되지 않은 일련의 줄(필요한 경우)을 인쇄하려면 ||또는를 사용하여 구분할 수 있습니다.;

awk 'NR==5,NR==10;NR==15,NR==20' logfile

특정 시간 범위 사이에 줄을 계속 인쇄하려면 위의 내용을 grep 과 결합하세요 egrep.

egrep "2018-04-12 14:44:01.000|2018-04-12 14:46:00.000" logfile | awk NR==5,NR==10

egrep여러 문자열이 반환될 수 있습니다. 이 |기호는 각 문자열을 구분합니다. 그러면 시간 범위의 시작 및 종료 시간(더 많은 행을 포함하기 위해 종료 시간을 나중 시간으로 변경함)과 해당 행 번호가 포함된 행이 인쇄됩니다. 그런 다음 를 사용하여 awk두 줄 사이(포함)의 범위를 인쇄 할 수 있습니다 .

이 모든 것을 예로 들어 로그 파일의 요구 사항과 시간에 따라 인쇄하려는 내용에 맞게 수정할 수 있습니다.

답변3

현재 비슷한 문제가 있지만1분 동안 로그가 없으면 "간단한" sed/awk 방식이 실패합니다.(예: 유휴 라우터)

마지막으로 생성된grep마지막 n분은 다음과 같이 선언됩니다.

searchterms() {
  backlog_minutes=15;
  for searchstamp in $(seq 0 60 $((60*backlog_minutes)));do
   LANG=en_US.UTF-8 date "+%b %d %H:%M" -d @"$(($(date +%s)-$searchstamp))";done ;
  } ;
greptarget=$(searchterms|sed 's/^/-e "/g;s/$/"/g' )

##Openwrt
which logread |grep -q logread && ( grepcmd=$(echo  grep  "$greptarget"); echo "logread|$(echo $grepcmd)"|sh )
## Linux Debian/Ubuntu
which logread |grep -q logread || (echo grep -e $greptarget /var/log/syslog|sh ;exit 0)

이전에 무엇을 시도했는가(https://unix.stackexchange.com/a/437445/374376)

##_date_syslog_15_min() { LANG=en_US.UTF-8 date "+%b %d %H:%M" -d "15 min ago"   ; } ;
##_date_syslog_now() { LANG=en_US.UTF-8 date "+%b %d %H:%M" ; } ;
## ↑↑ this ones failed when there are no log entries

답변4

당신은 이것을 할 수 있습니다sed

sed -n '/2018-04-12 14:44:00.000/,/2018-04-12 14:45:00.000/p' log_file

이는 첫 번째 인스턴스에만 일치하며 날짜를 구분 기호로 사용하여 인쇄한다는 점은 주목할 가치가 있습니다.

다음을 사용하여 비슷한 것을 얻을 수 있습니다 awk.

awk '/^2018-04-12 14:44:00.000.*/,/2018-04-12 14:45:00.000.*/' log_file

관련 정보