bash를 사용하여 시간 합계를 계산하는 방법은 무엇입니까?

bash를 사용하여 시간 합계를 계산하는 방법은 무엇입니까?

일련의 프로세스가 내 컴퓨터에서 실행되어야 하는지 아니면 더 강력한 컴퓨터에서 실행되어야 하는지 결정하는 데 걸리는 총 시간을 알고 싶습니다. 따라서 각 명령의 실행 시간을 예측합니다. 출력은 다음과 같습니다.

process1    00:03:34
process2    00:00:35
process3    00:12:34

총 실행 시간을 얻기 위해 두 번째 열을 어떻게 합산할 수 있나요? 각 행을 삽입해 볼 수 있습니다.

awk '{sum += $2 } END { print sum }

하지만 이는 그 값이 자연수가 아니기 때문에 의미가 없습니다.

답변1

#!/bin/sh

EPOCH='jan 1 1970'
sum=0

for i in 00:03:34 00:00:35 00:12:34
do
  sum="$(date -u -d "$EPOCH $i" +%s) + $sum"
done
echo $sum|bc

date -u -d "jan 1 1970" +%s0을 준다. 그러면 date -u -d "jan 1 1970 00:03:34" +%s214초가 됩니다.

답변2

이를 사용할 수 없거나 사용하고 싶지 않은 경우 TIMEFORMAT시간을 초로 변환한 다음 함께 추가하면 됩니다. 예를 들어 파이프를 통한 출력은 다음과 같습니다.

{                                           
sum=0
while IFS="[ :]" proc_name h m s
do
    let sum+=$((60*($m+60*$h)+$s)) 
done 
echo $sum  
} 

또는 원하는 경우 마지막 echo명령을 다음과 바꿀 수 있습니다.

printf "%02d:%02d:%02d\n" $[sum/3600] $[sum/60] $[sum%60]

답변3

고쳐 쓰다:

이는 dc. 합계가 60시간을 초과하면 다음과 같이 출력됩니다.4개3개가 아닌 공백으로 구분된 값입니다. (합계가 1시간 미만인 경우 공백으로 구분된 2개의 값만 출력됩니다.)

awk '{print $2}' file.txt | tr : \ | dc -f - -e '60o0ddd[+r60*+r60d**+z1<a]dsaxp'

질문에 표시된 대로 입력이 시, 분, 초의 세 번이라고 가정합니다.

제공된 입력의 출력은 다음과 같습니다.

 16 43

원래 답변:

dc데스크톱 계산기를 사용하여 이 작업을 수행해 보겠습니다 . 이는 Python의 백엔드이며 bc종종 신비롭다고 여겨지지만 매우 유연합니다.


먼저, 일부 전처리를 통해 시간만 제공하고 콜론을 공백으로 변환합니다.

awk '{print $2}' | tr : ' '

Sed를 사용하여 이 작업을 수행할 수도 있습니다.

sed -En -e 's/^.*([0-9][0-9]):([0-9][0-9]):([0-9][0-9]).*$/\1 \2 \3/p'

trAwk 가 더 간단하기 때문에 Awk를 선택하겠습니다 . 위 명령 중 하나는 다음 형식으로 깔끔한 출력을 생성합니다. (더 흥미로울 것 같아서 내 샘플 텍스트를 사용했습니다. 여기에는 시간도 포함되어 있습니다. 샘플 텍스트도 작동할 것입니다.)

$ cat input
9 39 42
8 04 50
7 49 32
10 01 54
7 19 18

위 형식으로 주어진 시간을 다음 Sed 스크립트를 통해 실행하고 dc아래와 같이 결과를 파이프합니다.

sed -e '1s/^/0 /' -e 's/$/ r 60 * + r 60 60 * * + +/' -e '$s/$/ 60 60 * ~ 60 ~ f/' input | dc

(사이드 스크롤을 줄이기 위해 분류했습니다 :)

sed <input \
    -e '1s/^/0 /' \
    -e 's/$/ r 60 * + r 60 60 * * + +/' \
    -e '$s/$/ 60 60 * ~ 60 ~ f/' |
      dc 

출력은 초, 분, 시간 순으로 표시됩니다. (참고로 이 순서는 역순입니다.) 배우는 중이 dc라 완벽한 해결책은 아니지만,하지만 얼핏 보면 꽤 괜찮아 보이는 것 같아요 dc.

터미널에서 직접 붙여넣은 입력 및 출력 예:

$ cat input 
9 39 42
8 04 50
7 49 32
10 01 54
7 19 18
$ sed -e '1s/^/0 /' -e 's/$/ r 60 * + r 60 60 * * + +/' -e '$s/$/ 60 60 * ~ 60 ~ f/' input | dc 
16
55
42
$ 

답변4

내 해결책은 다음과 같습니다. split().:를 사용하여 총 시간을 초 단위로 인쇄합니다.

awk '{
        split($2, tm, ":");
        tottm += tm[3] + tm[2] * 60 + tm[1] * 3600;
    }
    END {
        print tottm;
    }' ptime

적절한 시간 형식으로 인쇄하세요.

awk '{
        split($2, tm, ":");
        secs += tm[3]; 
        mins += tm[2] + int(secs / 60); 
        hrs += tm[1] + int(mins / 60);
        secs %= 60; mins %= 60;
    }
    END {
        printf "%d:%d:%d\n", hrs, mins, secs;
    }' ptime

GNU awk도 strftime을 지원하지만 현재 시간대를 사용하므로 결과가 혼란스러울 것입니다.

관련 정보