web-dev-qa-db-ja.com

bashスクリプトで2つのタイムスタンプを減算する

H:M:S.MSの形式でタイムスタンプのセットを含むファイルがあります。保存されたすべてのタイムスタンプを読み取って印刷できますが、減算(Timestamp2 - Timestamp1など)などの算術演算を実行すると答えを教えてください。私はbashスクリプトプログラミングの経験がありません。

任意の提案、推奨事項は大歓迎です。

これが私の問題の スクリーンショット です。

次に例を示します。

Start Time = 17:53:01.166721
End Time = 17:53:01.369787

End Time - Start Timeの予期される結果は、0:00:0.203066または0.203066のいずれかです。

10
Ali

単純なコマンドラインツールを使用して日付を処理する場合は、タイムスタンプをEpochベースのような扱いやすい形式に変換する必要があります。

これを行うには、dateコマンドを使用します。これは、次のような関数でラップできます。

timestamp() { 
   date '+%s%N' --date="$1"
}
# timestamp "12:20:45.12345"  ==>  1485105645123450000

次に、それらを直接差し引くことができます。

echo $(( $(timestamp "${Stime[$i]}") - $(timestamp "${Rtime[$i]}") ))

1日ではなく時間のみを追跡しているため、たとえば、開始時刻が23:59:59で終了時刻が00:00:01の場合、エラーが発生することに注意してください。

14
Grisha Levit

Bashを使用する必要がある場合は、タイムスタンプを整数値に変換する必要があります。

$ time="12:34:56.789"
$ IFS=":." read -r h m s ms <<<"$time"
$ echo $h $m $s $ms
12 34 56 789
$ milliseconds=$(( (h*3600 + m*60 + s)*1000 + ms ))
$ echo $milliseconds
45296789

次に、減算して、差分を表すミリ秒数を取得できます。

算術演算と文字列構成で秒に変換します。

$ seconds="$((milliseconds / 1000)).$((milliseconds % 1000))"
$ echo $seconds
45296.789

Gniourf_gniourfの有効なポイントに(不格好な方法で)対処するには:

$ time="12:34:56.7"
$ IFS=":." read -r h m s ms <<<"$time"
$ ms="${ms}000"; ms=${ms:0:3}
$ echo $h $m $s $ms
12 34 56 700
# .......^^^

また、「08」や「09」などの無効な8進数の文字列は、bash演算でエラーをスローするため、10を基数として明示的に宣言

milliseconds=$(( (10#$h*3600 + 10#$m*60 + 10#$s)*1000 + 10#$ms ))
3
glenn jackman

変数が整数であると仮定すると、それを機能させるには、計算を算術評価で囲む必要があります。

echo $(( VAR1 - VAR2 ))

または、値を割り当てる場合:

VAR3=$(( VAR1 - VAR2 ))
3
Fred