시차를 계산해야 해요
문서:
$ 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
e
GNU 플래그의 보안 영향에 신경 쓰지 않는다면 다음을 수행할 수 있습니다.
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