시간차 계산

시간차 계산

시차를 계산해야 해요

문서:

$ cat time.log
06:12:23
06:12:54
06:14:18
06:15:38
$

나는 그 결과가 다음과 같을 것으로 예상한다.

0:00:31
0:01:20

나는 이것을 시도했다

#!/bin/sh
cat "$@" |
tr : ' ' |
  dc -e '
[60+Lm1-Sm]SS
[60+Lh1-Sh]SM
[24+]SH
?SsSmSh
?SsSmSh
LsLs- d0>S Ss
LmLm- d0>M Sm
LhLh- d0>H Sh
[
]Ls[:]Lm[:]Lh
nnnnnn
'

하지만 결과는 다음과 같습니다

$ ./calculate_time.sh time.log 
0:0:31
$ 

처음 두 행 간의 차이만 가져오는데, 나머지 행 간의 차이도 가져오도록 하려면 어떻게 해야 합니까?

답변1

date계산할 수 있는 것으로 변환과 같은 도구를 사용하는 것은 어떨까요?

sed eGNU 플래그의 보안 영향에 신경 쓰지 않는다면 다음을 수행할 수 있습니다.

sed 'N;s/\(.*\)\n\(.*\)/date -d @$(($(date -d \2 +%s) - $(date -d \1 +%s))) -u +%H:%M:%S/e' time.log

따라서 date -d 6:12:43 +%s타임스탬프를 초로 변환하고 차이를 계산한 후 다시 변환할 수 있습니다 date -d 80 -u +%H:%M:%S. sed 스크립트는 이러한 줄을 결합하여 실행합니다.

답변2

해결책은 다음과 같습니다. 배열을 사용하여 코드를 재사용 bash하고 dc각 호출에 시간 문자열 쌍을 입력합니다.

#!/usr/bin/env bash

time=( $(< time.log) )
for ((i=0; i< ${#time[@]}; i+=2)); do
    printf '%s\n' "${time[i]}" "${time[i+1]}" |
    tr : ' ' |
    dc -e '
        [60+Lm1-Sm]SS
        [60+Lh1-Sh]SM
        [24+]SH
        ?SsSmSh
        ?SsSmSh
        LsLs- d0>S Ss
        LmLm- d0>M Sm
        LhLh- d0>H Sh
        [
        ]Ls[:]Lm[:]Lh
        nnnnnn
    ' | tr -d ' '
done

0:0:31
0:1:20

답변3

그리고 bash:

# line number
nr=1

while IFS=":" read -r h m s; do
  if [[ $nr%2 -eq 1 ]]; then
    # odd line
    t1=$(($h*60*60+$m*60+$s))
  else
    # even line
    t2=$(($h*60*60+$m*60+$s))

    # get diff in seconds
    d=$((t2-t1))

    # output diff in HH:MM:SS
    printf "%02d:%02d:%02d\n" $(($d/60/60%24)) $(($d/60%60)) $(($d%60))
  fi

  # increase line number by one
  nr=$(($nr+1))
done < time.log

산출:

00:00:31
00:01:20

답변4

모든 시간 쌍이 같은 날, 예를 들어 2023-05-06(분명히 어떤 날짜든 가능함)에 속한다고 가정하면 strptime()이를 Unix 타임스탬프로 변환한 다음 차이를 가져와 strftime().

우리는 할 수있어밀러( ) 다음과 같이 mlr쌍으로 시간 문자열을 읽습니다 .paste

paste - - <file |
mlr --tsv -N \
    put -s now=2023-05-06 '$tdiff = strftime(strptime(@now . " " . $2, "%F %T") - strptime(@now . " " . $1, "%F %T"), "%T")' then \
    cut -f tdiff

먼저 를 사용하여 입력 시간 문자열을 탭으로 구분된 쌍으로 별도의 줄에 넣습니다 paste. 그런 다음 Miller는 이를 헤더 없는 TSV 입력 스트림으로 읽고 put하위 명령을 사용하여 이름이 지정된 새 필드의 시간 차이를 계산합니다 tdiff. 그런 다음 하위 명령을 사용하여 cut이 새 필드만 추출합니다.

질문의 데이터가 주어지면 다음이 출력됩니다.

00:00:31
00:01:20

관련 정보