저는 현재 네트워크에서 생성된 syslog를 처리하기 위한 도구를 함께 만들고 있는데 요구 사항 중 하나는 날짜 시간을 syslog(%b %d %Y %T) 형식에서 에포크(epoch)로 변환하는 것입니다. 본질적으로 이것이 내가 달성하고 싶은 것입니다.
원래 시스템 로그 형식:
1: Jul 02 2019 15:14:19: %ASA-6-106015: <message>
2: Jul 02 2019 15:14:49: %ASA-6-106015: <message>
최종 로그:
1: 1562080489 %ASA-6-106015 <message>
2: 1562080529 %ASA-6-106015 <message>
전체 로그를 반복하고 date -d 작업을 수행하면 이 작업을 수행할 수 있다는 것을 알고 있습니다. 이것은 내가 피하고 싶은 것입니다. 나는 GAWK 시간 함수를 사용하는 것을 선호합니다.
이것이 나의 접근 방식입니다.
gawk -F: '{ print strftime("%s", timestamp}' syslog.log
그러나 여기의 타임스탬프는 systime() 함수에서 반환된 값과 동일한 형식이어야 합니다. 그러나 그것은 진실이 아니다.
또한 mktime() 함수는 특정 형식의 입력만 허용하므로 syslog 타임스탬프를 원하는 형식으로 변환하는 데 사용할 수 없습니다. [YYYY MM DD HH MM SS]
이 작업을 수행할 수 있는 방법이 있는 것 같지만 누락되었습니다. 대체 방법도 감사하겠습니다.
답변1
GNU를 사용하면 한 번 date
실행 date
하고 표준 입력에서 입력을 받을 수 있습니다. 사용gawk의 공동 프로세스 기능각각의 인스턴스를 갖고 awk
모든 date
날짜를 처리합니다.
% awk -v cmd='stdbuf -oL date +%s -f-' -F': ' 'BEGIN{OFS=FS} {print $2 |& cmd; cmd |& getline $2} 1' foo
1: 1562048059: %ASA-6-106015: <message>
2: 1562048089: %ASA-6-106015: <message>
알아채다date
출력을 버퍼링 해제해야 합니다.(따라서 stdbuf -oL
) 그렇지 않으면 coprocess가 중단됩니다.
답변2
해당 date(1)
유틸리티 와 마찬가지로 gawk
s는 mktime()
날짜 지정이 현지 시간을 사용한다고 가정합니다.
강제로 사용하려면 UTC
envvar TZ
를 사용해야 합니다.
$ TZ=UTC gawk -F'[: ]+' '{sub(/([^:]+:){4} */, mktime(sprintf("%s %02d %s %d %d %d", $3, index(" JanFebMarAprMayJunJulAugSepOctNovDec",$1)/3, $2, $4, $5, $6))"\t"$7"\t"); print}'
1562080459 %ASA-6-106015 <message>
1562080489 %ASA-6-106015 <message>
답변3
다음은 연관 배열을 사용하여 월 이름을 숫자로 변환하는 일반적인 방법입니다. 여기서 인덱스는 월 이름이고 값은 월 번호입니다. 예를 들어 mon["Jul"]
7입니다. 이는 BEGIN 블록에서 한 번 설정됩니다.
awk 'BEGIN {
split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec",months," ")
for(i=1;i<=12;i++)mon[months[i]] = i }
{ m = $2; d = $3; y = $4; t = $5; gsub(":"," ",t)
print mktime(y " " mon[m] " " d " " t) }'
그런 다음 각 행에 대해 필드가 올바른 순서로 다시 정렬되고 mktime()
중간 공백과 연결됩니다. 시간 필드가 공간 필드로 변환 t
되었습니다 . :
위의 내용은 에포크 시간만 인쇄하므로 나머지 데이터도 추가해야 합니다.
답변4
아마 펄:
perl -MTime::Piece -i.bak -pe '
if ( /([[:upper:]][[:lower:]]{2} \d{2} \d{4} \d\d:\d\d:\d\d)/ ) {
$datetime = Time::Piece->strptime($1, "%b %d %Y %T");
$epoch = $datetime->epoch;
s/$timestamp/$epoch/
}
' log_file