2014-09-04 2 views
0

나는 아래와 같은 형태의 로그 파일을했습니다 :계수 시간

log.txt에 내가 초 불가능 시간을 계산해야 할

Unavailable 06.08.2014 23:59:36 - 07.08.2014 00:00:36 
Unavailable 15.08.2014 04:53:32 - 15.08.2014 04:53:32 
Available 15.08.2014 04:54:32 - 15.08.2014 05:17:32 
Unavailable 15.08.2014 05:18:32 - 15.08.2014 05:18:32 
Unavailable 15.08.2014 08:22:00 - 15.08.2014 08:22:00 
Available 15.08.2014 08:23:00 - 17.08.2014 01:44:27 
Unavailable 17.08.2014 01:45:27 - 17.08.2014 01:52:33 
Available 17.08.2014 01:53:33 - 02.09.2014 11:07:21 

. 내가 어떤 SED/AWK 전문가 아니에요 그래서이 문제에 대한 나의 apporach은 매우 간단합니다 :

cat log.txt | grep "Unav" | sed -r 's/\<Unavailable\>//g;s/:/ /g;s/\./ /g' | 
awk -F- '{d2=mktime($2);d1=mktime($1);print d2-d1;}' | awk '{s+=$1} END {print s}' 

나는 날짜가 하루 건너 온 (저점 자정) 계산이 잘못되는 것을보고 놀라게했다. 첫 번째 라인의 계산 결과는 EPOCH에서 차이가 초임을 나타내므로 Thu Dec 31 01:01:00 CET 1970이됩니다. 그러나 계산 결과는 60 초입니다. 왜이 결과가 시스템에서 반환되었는지 설명 할 수 있습니까?

답변

3

awk을 사용하려는 경우 모두 sedgrep이 필요하지 않습니다. 또한 샘플 데이터에서 보여주는 것처럼 차이는 60 초 여야합니다. man 페이지에서

: SYSTIME에 의해 반환 그대로

한다 mktime (datespec)이 같은 형태의 타임 스탬프로 datespec십시오(). 인수 C는 ISO C에서 동일한 이름 의 함수와 유사합니다. arguments datespec은 "YYYY MM DD HH MM SS [DST]"형식의 문자열입니다.

다음 명령을 시도해보십시오

awk ' 
$1 == "Unavailable" { 
    split ($2, d1, /[.]/); 
    split ($3, t1, /:/); 
    split ($5, d2, /[.]/); 
    split ($6, t2, /:/); 
    end = mktime (d2[3]" "d2[2]" "d2[1]" "t2[1]" "t2[2]" "t2[3]) 
    start = mktime (d1[3]" "d1[2]" "d1[1]" "t1[1]" "t1[2]" "t1[3]) 
    print end - start 
}' log.txt 
60 
0 
0 
0 
426 

이 초 차이를 인쇄합니다. 출력을 다른 형식으로 인쇄하려면 GNU awk 라이브러리의 strftime 기능을 사용할 수 있습니다.

+1

내가 말하는 것은 awk 전문가가 아니지만 나는 당신이 많이 감사하다는 것을 알 수 있습니다. – michalp

+1

"내가 게시 한 답변은 어디에서 왔는지"에 대한 귀하의 의견을 업 그레 이드 할 수 없으므로 여기에서 설명합니다. D – fedorqui

0

내 시스템에서 man awkmktime(datespec)의 형식이 YYYY MM DD HH MM SS이어야한다고 말합니다. 그러나 당신은 06 08 2014 23 59 36을 전달하고 있으며, 이는 하루와 스왑을 교환합니다. 필드를 재정렬해야합니다.