我正在从各自的日志文件中获取文件中各种进程的执行时间。带有执行时间的文件看起来类似于以下(它可能有数百个条目)
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
的组件。
date
和 GNU awk
的(非标准)日期格式化函数不能用于格式化输出的原因是双重的:
标准时间格式说明符
%H
环绕 24 小时,因此如果累计时间跨度超过 24 小时,输出将不正确。小数秒会丢失(Unix 时间戳的粒度是整秒)。
关于bash - bash 中的持续时间总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42354087/