syslog 날짜 시간[UTC]을 에포크로 변환하는 방법은 무엇입니까?

syslog 날짜 시간[UTC]을 에포크로 변환하는 방법은 무엇입니까?

저는 현재 네트워크에서 생성된 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)유틸리티 와 마찬가지로 gawks는 mktime()날짜 지정이 현지 시간을 사용한다고 가정합니다.

강제로 사용하려면 UTCenvvar 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

관련 정보