bash - bash 中的持续时间总和

标签 bash perl awk

我正在从各自的日志文件中获取文件中各种进程的执行时间。带有执行时间的文件看起来类似于以下(它可能有数百个条目)

1:00:01.11
2:2.20
1.02

第一行是hours:minutes:seconds,第二行是minutes:seconds,第三行是seconds

我想将所有条目加起来得出总执行时间。我怎样才能在 bash 中做到这一点?如果不是 bash,那么您能否提供一些其他脚本语言的示例来求和时间戳?

最佳答案

补充Matt Jacob's elegant perl solution使用(符合 POSIX 标准的)awk 解决方案:

awk -F: '{ n=0; for(i=NF; i>=1; --i) secs += $i * 60 ^ n++ } END { print secs }' file

使用示例输入,此输出(所有时间跨度的总和,以 为单位):

3724.33

请参阅下面的部分,了解如何将此值格式化为时间跨度,类似于输入 (01:02:04.33)。

解释:

  • -F: 通过:将输入行分割成字段,这样得到的字段($1, $2, ...) 分别表示小时、分钟和秒组件。

  • n=0; for(i=NF; i>=1; --i) secs += $i * 60 ^ n++ 以相反的顺序枚举字段(先是秒,然后是分钟,然后是小时,如果已定义; NF 是字段数)并将每个字段乘以 60 的适当倍数以产生以秒为单位的总值,存储在变量 secs 中,跨行累积。

  • END { print secs } 在处理完所有行后执行,并简单地打印以秒为单位的累积值。


将输出格式化为时间跨度:

必须使用自定义输出格式:

awk -F: '
  { n=0; for(i=NF; i>=1; --i) secs += $i * 60 ^ n++ }
  END { 
    hours   = int(secs / 3600)
    minutes = int((secs - hours * 3600) / 60)
    secs    = secs % 60
    printf "%02d:%02d:%05.2f\n", hours, minutes, secs
  }
' file

以上产量(相当于 3724.33 秒):

01:02:04.33

END { ... } block 将 secs 中累积的总秒数拆分回小时、分钟和秒,并以适当的格式输出结果使用 printf 的组件。

dateGNU awk 的(非标准)日期格式化函数不能用于格式化输出的原因是双重的:

  • 标准时间格式说明符 %H 环绕 24 小时,因此如果累计时间跨度超过 24 小时,输出将不正确。

  • 小数秒会丢失(Unix 时间戳的粒度是整秒)。

关于bash - bash 中的持续时间总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42354087/

相关文章:

bash - 如何使whiptail中的输入框超时?

c++ - 如何使用 gnu_parallel 运行多个可执行文件和/或 bash 脚本?

bash - : and := inside a bash parameter expansion

html - 从 Html 文件 <td> 元素中提取值

bash - 试图将一个字符串拆分为两个变量

json - 如何解析这个 JSON 对象/字符串?

regex - 在 Perl 中使用正则表达式拆分字符串

python - Bash 与 Perl/Python : OS call perfomace

AWK 为 sub/gsub 返回数字而不是字符串

bash - 我的 awk 用户函数无法在 bash 脚本中运行