我希望在bash中计算多个命令所花费的平均时间。time命令的输出格式为分:秒.毫秒。
我不知道如何在bash中将两个这种类型的输出相加,并最终计算平均值。
我尝试使用date将输出转换,但输出为“date: invalid date `0:01.00'”。
我不知道如何在bash中将两个这种类型的输出相加,并最终计算平均值。
我尝试使用date将输出转换,但输出为“date: invalid date `0:01.00'”。
这是一个由三部分组成的答案
首先,使用TIMEFORMAT
变量仅输出经过的秒数。然后您可以直接添加此内容。
来自man bash
TIMEFORMAT 此参数的值用作格式字符串,指定如何显示以time保留字为前缀的管道的计时信息。%字符引入扩展为时间值或其他信息的转义序列。转义序列及其含义如下;花括号表示可选部分。
以下是一个示例,仅输出精确到秒的秒数,即没有小数点。请阅读第三部分,了解为什么这很重要。
TIMEFORMAT='%0R'; time sleep 1
1
其次,我们如何捕获time
的输出?这有点棘手,以下是如何从上述命令中捕获时间:
TIMEFORMAT='%0R'; time1=$( { time sleep 1; } 2>&1 )
我们如何将时间相加并得到平均值?
在bash中,我们使用$(( ))
结构来进行数学运算。请注意,bash
不支持浮点数,因此您将进行整数除法(因此精度为0)。以下是一个脚本,它将捕获两个命令的time
并输出每个单独的时间及其平均值。
#!/bin/bash
TIMEFORMAT='%0R'
time1=$( { time sleep 1; } 2>&1 )
time2=$( { time sleep 4; } 2>&1 )
ave=$(( (time1 + time2) / 2))
echo "time1 is $time1 | time2 is $time2 | average is $ave"
time1 is 1 | time2 is 4 | average is 2
bc
,你可以很容易地实现这一点。#!/bin/bash
TIMEFORMAT='%3R'
time1=$( { time sleep 1; } 2>&1 )
time2=$( { time sleep 4; } 2>&1 )
ave=$( bc <<<"scale=3; ($time1 + $time2)/2" )
echo "time1 is $time1 | time2 is $time2 | average is $ave"
time1 is 1.003 | time2 is 4.003 | average is 2.503
为了举例,我将使用一个预初始化的变量:
time="54:32.96";
minutes=$(echo "$time" | cut -d":" -f1)
seconds=$(echo "$time" | cut -d":" -f2 | cut -d"." -f1)
millis=$(echo "$time" | cut -d":" -f2 | cut -d"." -f2)
#Total time in millis
totalMillisOne=$(($millis+$seconds*1000+$minutes*60000))
你需要对每个命令进行操作,并将其保存在不同的变量中,然后计算平均值:
let avMillis=$totalMillisOne+$totalMillisTwo
let avMillis=$avMillis/2
然后你以相同的输入格式输出它:
let avSeconds=$avMillis/1000
let avMillis=$avMillis-$avSeconds*1000;
let avMinutes=$avSeconds/60;
let avSeconds=$avSeconds-$avMinutes*60;
echo "${avMinutes}:${avSeconds}.${avMillis}"
bash
中,您可以使用cut -d:-f1 <<< $time
来简化echo
部分。例如。您还可以使用纯Bash进行字符串操作,避免调用外部命令。我可能会在一个Perl(Python,awk,...)命令中完成整个操作,但这部分是因为我尚未内化bash
中所有可用的功能。还要注意,显示的时间值将转换为3272.096而不是3272.960。 - Jonathan Leffler