Linux에서 경과 시간을 초 단위로 구문 분석하는 방법

Linux에서 경과 시간을 초 단위로 구문 분석하는 방법

경과 시간을 초 단위로 분석하고 싶습니다. 시간 형식은 다음과 같습니다.

1) 3 day 18h
2) 3 day
3) 3h 15min
4) 3h 
5) 15min 10sec
6) 15min 
7) 10sec

나는 그것으로부터 가치를 얻는다systemctl status cassandra | awk '/(Active: active)/{print $9, $10,$11}'이제 다음과 같이 변수 A에 값을 저장하십시오.

A=$(systemctl status cassandra | awk '/(Active: active)/{print $9, $10,$11}'

이제 A는 3 day 18hor 3 day등 으로 들어갑니다. 더 많은 예 -

A=3 day 18h or 3 day or 3h 15min or 3h or 15min 10sec or 15min or 10sec

이제 다양한 A 값을 가져와 몇 초 만에 구문 분석해 보세요.

답변1

date명령을 사용하여 다음과 같이 이러한 값을 구문 분석할 수 있습니다 .

        adjusted_val="$(printf '%s' "$val" | sed 's/h/hour/')"
        result="$(date -d "$(date -d @0) + $adjusted_val" +%s)"

이상하게도 "hour"의 약어를 (심지어 ) date인식하지 못하므로 첫 번째 단계로 문자열을 로 바꿉니다 . 그런 다음 (Unix 시간 0)을 문자열로 확장하여 "에포크 시간"(Unix 날짜/시간 카운트의 날짜/시간)을 찾습니다 . (우리 모두 알고 있듯이 기록은 "1970년 1월 1일 00:00:00 GMT"이므로 해당 값을 하드코딩할 수 있습니다.) 그런 다음 문자열을 추가합니다. 예를 들어 (1월 1일) + 3일(s)은 1월 4일. 그런 다음 해당 날짜/시간을 Unix 숫자 날짜/시간으로 표시합니다. 이는 에포크 이후의 초 수입니다. 이는 문자열의 간격(증분) 값에 해당합니다.hhrhhour@0+%s

한 번에 여러 값에 대해 이를 수행하려면 에포크를 한 번만 계산하여 최적화할 수 있습니다.

#!/bin/sh
epoch="$(date -d @0)"
for val
do
        adjusted_val="$(printf '%s' "$val" | sed 's/h/hour/')"
        if result="$(date -d "$epoch + $adjusted_val" +%s)"
        then
                printf '%-12s -> %6d\n' "$val" "$result"
        else
                printf '%-12s <- error\n' "$val"
        fi
done

결과:

$ ./myscript '3 day 18h' '3 day' '3h 15min' '3h' '15min 10sec' '15min ' \
                                                       '10sec' 'a moment' '3 weeks'
3 day 18h    -> 324000
3 day        -> 259200
3h 15min     ->  11700
3h           ->  10800
15min 10sec  ->    910
15min        ->    900
10sec        ->     10
date: invalid date ‘Wed, Dec 31, 1969  7:00:00 PM + a moment’
a moment     <- error
3 weeks      -> 1814400

date -d"월"이라는 단어가 처리될 수 있다는 점에 유의하세요 . 해당 단어가 포함된 값을 얻는 것이 가능하다면 sed"월"의 "h"가 변경되지 않도록 명령을 더 스마트하게 만들어야 합니다.

하지만 정말로 달을 다루고 싶다면 "한 달"이 무엇인지 정말로 생각해 봐야 합니다. 예를 들어, 나는 이 글을 2020년 4월 12일에 쓰고 있습니다. 한 달 뒤인 5월 12일, 30일 남았습니다. 한 달 전이 3월 12일, 그러니까 31일 전이었습니다. 두 달 전인 2월 12일, 그러니까 60(31+29)일 전이었습니다. 하지만 윤년이 아닌 해에는 2월이 28일밖에 없으므로 2월 12일과 4월 12일은 59일밖에 차이가 나지 않습니다. 더 많은 것들이 있습니다: (적어도) 미국에서는 2월 12일이 표준시이고 3월 12일이 일광 절약 시간제이므로 (윤년이 아닌 해의 경우) 2월 12일 정오와 3월 12일 정오는 단지 27일, 즉 23일 간격입니다. 시간. 복잡해요.

답변2

7일 후에는 주 매개변수를 얻고 30일 후에는 월 매개변수를 얻게 되므로 일 및 시간 매개변수에 의존할 수 없습니다.

따라서 서비스 시작 시간을 이용하여 계산하는 것이 가장 좋습니다.

#!/bin/bash
SERVICE=cassandra
SERVICE_START_TIME=`systemctl status $SERVICE | awk '/Active: active/{print $6" "$7}'`
SERVICE_UP_TIME=$(($(date +%s) - $(date -d "$SERVICE_START_TIME" +%s)))
echo "$SERVICE uptime : $SERVICE_UP_TIME"

다음 코드 줄을 사용해 볼 수 있지만 정확한 결과를 얻으려면 위 코드를 사용하는 것이 좋습니다.

systemctl status cassandra | awk -F ';' '/Active: active/{print $2}' |  sed -e 's/s ago/ 1/; s/s//g; s/min/ 60/; s/h ago/ 3600/; s/day/86400/; s/week/606800/; s/month/2592000/; s/ago//' | awk '{a=$1*$2;b=$3*$4;c=$a+$b;print a" sec"}'

관련 정보