![Perl을 사용하여 로그 구문 분석](https://linux55.com/image/129498/Perl%EC%9D%84%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC%20%EB%A1%9C%EA%B7%B8%20%EA%B5%AC%EB%AC%B8%20%EB%B6%84%EC%84%9D.png)
로그를 구문 분석하기 위해 설계한 Perl 명령을 사용하고 싶습니다. 지금까지 내가 달성하려고 하는 것은 특정 타임스탬프 형식을 추출하고 호스트를 검색하는 것입니다. 로그는 다음과 같습니다
2016-05-07T09:07:04.933343+00:00 heroku[router]: status=301 bytes=680 service=2698ms connect=1ms dyno=web.2 fwd="10.29.10.29" at=info host="jamaican.com" request_id=32fc8d88-99f8-4cc2-89f9-284d059eebf8 method=GET path="/blog"
내 명령은 원하는 날짜 형식을 구문 분석할 수 있지만 출력에 호스트를 추가하는 방법을 알 수 없는 것 같습니다. 어떤 제안이라도 좋을 것입니다!
cat test.log |
perl -lne 'print $1 if /^([0-9]+[-]+[0-9]+[0-9]+[-]+[0-9]+[0-9]+[T]+[0-9]+[0-9]+[:]+[0-9]+[0-9]+[:]+[0-9]+[0-9])/'
답변1
이 시도:
perl -nle'($time, $host) = /^(\S+)\s(?:\S+\s+){8}\S+="(\S+?)"/; print "$time $host"'
산출:
2016-05-07T09:07:04.933343+00:00 jamaican.com
\S
비공간을 나타냄\s
공간이다(?:)
잡히지 않은 논리적 그룹화입니다.{8}
건너뛴 "단어"입니다.\S+="(\S+?)"
=
의미: 두 따옴표 사이에 있는 내용 까지 건너뛰고 캡처합니다."
($time, $host) = /.../
캡처된 두 그룹을$time
및$host
답변2
호스트 이름을 캡처하려면 두 번째 캡처 그룹을 사용해야 합니다.
예를 들어 예제 입력을 사용하면 다음과 같습니다.
$ cat test.log
2016-05-07T09:07:04.933343+00:00 heroku[router]: status=301 bytes=680 service=2698ms connect=1ms dyno=web.2 fwd="10.29.10.29" at=info host="jamaican.com" request_id=32fc8d88-99f8-4cc2-89f9-284d059eebf8 method=GET path="/blog"
이 perl one-liner는 타임스탬프와 호스트 이름 필드를 추출합니다. 또한 \d
각 숫자에 일치 횟수가 있는 숫자 에 대한 정규식을 일부 개선했습니다 .
$ perl -lne 'print "$1 $2" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}) ([^ ]+) /)' test.log
2016-05-07T09:07:04.933343+00:00 heroku[router]:
또 다른 옵션:
$ perl -lne 'print "$1 $2 $3" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}) ([^[]+)\[([^]]+)\]/)' test.log
2016-05-07T09:07:04.933343+00:00 heroku router
host="jamaican.com"
나는 당신이 당신의 로컬 컴퓨터의 호스트 이름을 원한다고 가정합니다. (저는 로그 항목 부분 도 눈치 채지 못했습니다 ). 이는 원하는 것이 아닐 수 있으므로 호스트 이름 뒤에 큰따옴표를 사용하려면 host=
다음을 수행하세요.
$ perl -lne 'print "$1 $2" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}).*host="([^"]+)"/)' test.log
2016-05-07T09:07:04.933343+00:00 jamaican.com
또는 (더 쉽게):
$ perl -lne 'print "$1 $2" if (m/(^\S+).*host="([^"]+)"/)' test.log
2016-05-07T09:07:04.933343+00:00 jamaican.com
또는 타임스탬프를 추출하고 .를 Date::Parse
사용하여 구문 분석한 다음 Date::Format
.
$ perl -MDate::Parse -MDate::Format -lne \
'if (m/(^\S+).*host="([^"]+)"/) {
print join(" ", time2str("%Y-%m-%d %R %z",str2time($1)), $2)
}' test.log
2016-05-07 19:07 +1000 jamaican.com
참고: 타임스탬프는 현지 시간대로 변환됩니다(나의 경우 +1000 또는 호주 동부 표준시). time2str()
기본적으로 현지 시간대가 사용되지만 세 번째 인수( time2str(TEMPLATE, TIME [, ZONE])
)를 지정하여 다른 시간대의 시간을 출력하도록 할 수 있습니다.
$ perl -MDate::Parse -MDate::Format -lne 'if (m/(^\S+).*host="([^"]+)"/) {
print join(" ", time2str("%Y-%m-%d %R %z",str2time($1),"+0"), $2)
}' test.log
2016-05-07 09:07 +0000 jamaican.com