如何在bash脚本中存储“time”函数输出的子字符串

时间:2010-12-16 06:10:37

标签: regex linux bash time

因此bash的内置时间函数应该以这种格式输出

real 0m0.002s
user 0m0.001s
sys  0m0.000s

我想以毫秒为单位保存用户时间,比如001这样做的干净方法是什么?

3 个答案:

答案 0 :(得分:10)

干净的方法是使用TIMEFORMAT shell变量来仅打印用户信息。 (man bash了解更多详情。)

然后,当然你需要捕获它的输出。这是不可能从管道执行的,因为它是由shell内部完成的,但您可以在子shell中运行它,输出将转到标准错误。但是你必须以某种方式将命令的输出重定向到其他地方。在这里,我只是丢弃它,但是存在许多其他可能性,具体取决于你需要做什么。然后,您需要将d.ddd发送到dddd。只需删除期限即可。

(TIMEFORMAT="%U"; time ls > /dev/null) |& tr -d .

如果您愿意,可以添加| sed s/^0*//以消除前导零。

%R将给出实时,%S系统时间。您可以使用例如更改精度%6U可以获得微秒,但大多数系统都不会接近那么精确。

man bash有关重定向的帮助。 man trman sed有关如何使用它们的帮助。

答案 1 :(得分:9)

Bash的time内置函数有点难以捕获,因为它具有特殊处理能力,因此它可以返回整个管道(如time ls -l | sort | uniq)的处理时间,而不仅仅是ls -l的处理时间。我的例子中有1}}命令。

捕获只是时间输出的最佳方法是以下重定向技术:

exec 3>&1 4>&2
foo=$( { time some_command 1>&3 2>&4; } 2>&1 ) # change some_command
exec 3>&- 4>&-

此时如果您echo "$foo",您会看到

的顺序
real    0m0.013s
user    0m0.004s
sys     0m0.007s

现在要获得004部分,你有很多选择:sed,awk或者直接bash来命名前3名。我个人最喜欢的是awk,它看起来像这样:< / p>

foo=$({ time some_command 1>&3 2>&4;} 2>&1 | awk -F'[s.]' '/user/{print $3}')

现在,如果您echo "$foo",则会根据需要看到004

答案 2 :(得分:1)

使用bash的内置字符串通配,你可以这样做:

output="real 0m0.002s
user 0m0.001s
sys  0m0.000s"

#get everything to the right of first "*user "
user=${output#*user }
#get everything to the left of the first "s*"
user=${user%%s*}
#get everythig to let left of "m*"
min=${user%%m*}
#get everything to the right of "*m" and left of ".*"
sec=${user#*m}
sec=${sec%%.*}
#get everything to the right of "*."
usec=${user#*.}


time=$[$usec + $sec * 1000 + $min * 60000]

运行bash -x

的结果
+ output='real 0m0.002s
user 0m0.001s
sys  0m0.000s'
+ user='0m0.001s
sys  0m0.000s'
+ user=0m0.001
+ min=0
+ sec=0.001
+ sec=0
+ usec=001
+ time=1