時差を計算する必要があります。
文書:
$ 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
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