我从各自的日志文件中获取文件中各种进程的执行时间.具有执行时间的文件看起来类似于以下(它可能有数百个条目)
1:00:01.11
2:2.20
1.02
Run Code Online (Sandbox Code Playgroud)
第一行是hours:minutes:seconds,第二行是minutes:seconds,第三行是seconds.
我想将所有条目总和到总执行时间.我怎样才能在bash中实现这一目标?如果不是bash,那么你可以提供一些其他脚本语言的例子来总结时间戳吗?
最常见的完整perl脚本:
use strict;
use warnings;
my $seconds = 0;
while (<DATA>) {
my @fields = reverse(split(/:/));
for my $i (0 .. $#fields) {
$seconds += $fields[$i] * 60 ** $i;
}
}
print "$seconds\n";
__DATA__
1:00:01.11
2:2.20
1.02
Run Code Online (Sandbox Code Playgroud)
或者,几乎不可读的单行版本:
$ perl -F: -wane '@F = reverse(@F); $seconds += $F[$_] * 60 ** $_ for 0 .. $#F; END { print "$seconds\n" }' times.log
Run Code Online (Sandbox Code Playgroud)
输出:
3724.33
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,我们在H:M:S分隔符上拆分每一行:,然后反转数组,以便我们可以从右到左进行处理.为了获得以秒为单位的总时间,我们可以依靠一个巧妙的技巧,我们将每个字段乘以60的幂.
如果您希望结果采用H:M:S格式而不是原始秒数,那么strftime()从POSIX核心模块可以轻松实现:
use POSIX qw(strftime);
print strftime('%H:%M:%S', gmtime($seconds)), "\n";
Run Code Online (Sandbox Code Playgroud)
输出:
01:02:04
Run Code Online (Sandbox Code Playgroud)
用(符合 POSIX 标准的)解决方案补充Matt Jacob 的优雅perl解决awk方案:
awk -F: '{ n=0; for(i=NF; i>=1; --i) secs += $i * 60 ^ n++ } END { print secs }' file
Run Code Online (Sandbox Code Playgroud)
使用样本输入,输出(所有时间跨度的总和,以秒为单位):
3724.33
Run Code Online (Sandbox Code Playgroud)
请参阅下面的部分,了解如何将此值格式化为时间跨度,类似于输入 ( 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
Run Code Online (Sandbox Code Playgroud)
以上产量(相当于3724.33秒):
01:02:04.33
Run Code Online (Sandbox Code Playgroud)
该END { ... }块将累积的总秒数拆分secs为小时、分钟和秒,并使用printf.
不能使用date和GNU awk的(非标准)日期格式化函数等实用程序来格式化输出的原因有两个:
标准时间格式说明符%H 环绕在 24 小时,因此如果累积时间跨度超过 24 小时,输出将不正确。
小数秒会丢失(Unix 时间戳的粒度是 整秒)。
| 归档时间: |
|
| 查看次数: |
215 次 |
| 最近记录: |