다음을 기준으로 로그 파일을 필터링하려고 합니다.
잘못된 날짜 범위(yyyy-mm-dd)
잘못된 타임스탬프 범위(01:00:00 - 00:00:00)
키워드(previousFireTime, nextFireTime)
로그 파일을 사용해 보았 grep
으나 제대로 작동하지 않습니다 . 필요한 정보를 얻으려면 및 또는 를 조합하여 grep
사용해야 합니까 ? 아니면 로그 파일을 필터링하는 더 좋고 효율적인 방법이 있습니까?awk
grep
awk
sed
편집: 샘플 로그 출력
2018-06-06 10:46:43,708 INFO [stdout] (AsyncAppender-Worker-STDOUT) INFO
[erFactoryBean_Worker-9] [c.c.c.s.i.d.ResendJob] Executing Quartz scheduled
job: JobExecutionContext: trigger: 'ResendJob.trigger_ResendJob job:
DEFAULT.ResendJob fireTime: 'Wed Jun 06 10:46:43 UTC 2018 scheduledFireTime:
Wed Jun 06 10:46:43 UTC 2018 previousFireTime: 'Wed Jun 06 10:45:43 UTC 2018
nextFireTime: Wed Jun 06 10:47:43 UTC 2018 isRecovering: false refireCount: 0
답변1
awk
정규식 일치를 수행하고, 행을 필드로 분할하고, 문자열 비교를 수행할 수 있으므로 필요할 수 있습니다(YYYY-MM-DD HH:MM:SS 타임스탬프를 사용하고 DST 변경이 없는 한 날짜 비교에 적합합니다). .
날짜가 첫 번째 필드에 있고 시간이 두 번째 필드에 있는 경우:
awk -v date=1 -v time=2 '
$date > "2018-05-24" && $time < "12:00:00" && /some text/'
GNU awk 구현에는 awk
다음과 같은 고급 작업을 수행할 수 있는 날짜 구문 분석 및 형식 지정 확장 기능이 있습니다.
gawk -v date=1 -v time=2 '
function parse_time(t) {
gsub(/[:-]/, " ", t)
return mktime(t)
}
BEGIN {
start = parse_time("2018-01-01 08:00")
end = systime() - 86400 # yesterday, same time
}
{t = parse_time($date" "$time)}
t >= start && t <= end && /some test/'
답변2
grep은 정규식을 필터링합니다. 특정 키워드가 포함된 행을 필터링하는 데는 매우 효과적이지만 정규식을 사용하여 날짜 범위를 지정하는 것은 어렵습니다. 예를 들어 1월 1일 20시부터 1월 3일 2시 사이에 오류가 발생하려면 1월 2일에는 모든 시간을 수락해야 하지만 1월 1일 밤과 1월 3일 이른 아침만 허용됩니다. 예를 들어, 시간과 날짜를 분리할 수 없습니다.
로컬에서 날짜를 비교할 수 있는 보다 표현력이 뛰어난 도구를 사용하는 것이 훨씬 간단합니다. Perl은 이를 수행하는 데 널리 사용되는 언어이며 Python이 좋은 선택입니다.
다음은 Python 예제입니다.
import re
import time
f = open('/var/log/syslog')
line = f.readline()
while line:
# Get the date at the beginning of line with a regex
m = re.match(r'^([^\s]+\s+[^\s]+\s+[^\s]+)\s+', line)
# Parse the date
date = time.strptime(m.group(1), '%b %d %H:%M:%S')
# Compare with a given date
if date > time.strptime('Jun 6 14:00:00', '%b %d %H:%M:%S'):
print(line, end='')
# Read next line
line = f.readline()