解析Bash';s时间内置

解析Bash';s时间内置,bash,parsing,awk,command,output,Bash,Parsing,Awk,Command,Output,我正在从Bash脚本运行一个C程序,并通过一个名为time的命令运行它,该命令为算法的运行输出一些时间统计信息 如果我执行命令 time $ALGORITHM $VALUE $FILENAME 它产生以下输出: real 0m0.435s user 0m0.430s sys 0m0.003s 值取决于算法的运行 然而,我希望能够做的是取0.435并将其分配给一个变量。 我已经读了一点awk,足以知道如果我将上述命令导入awk,我应该能够获取0.435并将其放入变量中。但是

我正在从Bash脚本运行一个C程序,并通过一个名为time的命令运行它,该命令为算法的运行输出一些时间统计信息

如果我执行命令

time $ALGORITHM $VALUE $FILENAME
它产生以下输出:

real    0m0.435s
user    0m0.430s
sys     0m0.003s
值取决于算法的运行

然而,我希望能够做的是取0.435并将其分配给一个变量。 我已经读了一点awk,足以知道如果我将上述命令导入awk,我应该能够获取0.435并将其放入变量中。但是我该怎么做呢


非常感谢

您可以尝试下面的awk命令,该命令使用split函数根据
数字m
或最后一个
s
分割输入

$ foo=$(awk '/^real/{split($2,a,"[0-9]m|s$"); print a[2]}' file)
$ echo "$foo"
0.435
您可以使用此awk:

var=$(awk '$1=="real"{gsub(/^[0-9]+[hms]|[hms]$/, "", $2); print $2}' file)
echo "$var"
0.435

您必须小心:有Bash内置的
time
,还有外部命令
time
,通常位于
/usr/bin/time
(键入
type-a time
,以便在您的系统上拥有所有可用的
time

如果您的shell是Bash,那么当您发布

time stuff
您正在调用内置的
time
。如果没有一些小技巧,您无法直接捕获时间的输出。这是因为
time
不想干扰可能执行的重定向或管道,这是一件好事

要在标准输出上获得
时间
输出,您需要:

{ time stuff; } 2>&1
(分组和重定向)

现在,关于解析输出:解析命令的输出通常不是一个好主意,尤其是当可以不解析命令时。幸运的是,Bash的
time
命令接受一个格式字符串。从手册中:

TIMEFORMAT

此参数的值用作格式字符串,指定以时间保留字为前缀的管道的计时信息应如何显示。
%
字符引入一个转义序列,该序列扩展为时间值或其他信息。逃逸序列及其含义如下:;大括号表示可选部分

%%

   A literal `%`.
%[p][l]R

   The elapsed time in seconds.
%[p][l]U

   The number of CPU seconds spent in user mode.
%[p][l]S

   The number of CPU seconds spent in system mode.
%p

   The CPU percentage, computed as (%U + %S) / %R. 
可选的
p
是一个数字,指定精度,小数点后的小数位数。值为0时,不会输出小数点或分数。小数点后最多可指定三位;大于3的p值更改为3。如果未指定
p
,则使用值3

可选的
l
指定了更长的格式,包括分钟,格式为
MMmSS.FFs
p
的值决定是否包含分数

如果未设置此变量,Bash的行为就好像它具有该值一样

$”\nreal\t%3lR\n用户\t%3lU\nsys\t%3lS'

如果该值为空,则不显示计时信息。显示格式字符串时,将添加一个尾随换行符

因此,要完全实现您的目标:

var=$(TIMEFORMAT='%R'; { time $ALGORITHM $VALUE $FILENAME; } 2>&1)
正如所指出的,如果您的命令将任何消息发送到标准输出和标准错误,您也必须注意这一点。为此,需要一些额外的管道:

exec 3>&1 4>&2
var=$(TIMEFORMAT='%R'; { time $ALGORITHM $VALUE $FILENAME 1>&3 2>&4; } 2>&1)
exec 3>&- 4>&-

来源:非常棒。

你想只存储
0.435
这一行吗?感谢@fedorqui的可能副本,在花了4年多的时间之后,你将拥有超过200ky的数据。你需要这些数字的特殊技能,我会坐下来欣赏你的大师:)恭喜!注意
time
的输出通常会转到stderr,因此您必须重定向。感谢您的帮助。到目前为止,我已经试过了,但是它打印出了原始输出,而不是0.435 Note
time
的输出通常会转到stderr,所以你必须重定向。@Struan,如果$ALGORITHM命令向stdout发出任何信息,你需要在
2>&1
@glennjackman之后添加
1>/dev/null
,这太棒了。我正要发布另一条关于为什么输出有点滑稽的帖子,但你帮了我这个忙。谢谢@glennjackman关于
$ALGORITHM
的输出,您完全正确。我已经加了一句话。谢谢。如果有人感兴趣的话,我最终用它创建了一个时间复杂度图来分析我一直在写的算法的性能。下面是it运行的一个例子:再次感谢大家的帮助!