時間差の計算

時間差の計算

時差を計算する必要があります。

文書:

$ 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
$ 

最初の2つの行間の違いのみを取得しますが、残りの行間の違いも取得するにはどうすればよいですか?

答え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

解決策は次のとおりです。配列を使用してコードを再利用し、bashdc呼び出しに時間文字列のペアを入力します。

#!/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

関連情報