计算时间差

计算时间差

我需要计算时差

文件:

$ 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为什么不使用像转换为可以计算的东西这样的工具呢?

如果您不介意 GNUsed e标志的安全含义,您可以这样做

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

相关内容