sleep
,
比如“3d 7h 5m 10s”(3天7小时5分10秒),
这将导致:
(3 * 24 * 60 * 60) + (7 * 60 * 60) + (5 * 60) + 10 = 284710
秒
请注意,这 4 个元素并非全部都必须存在,且顺序也不正确, 并且一个元素可能会出现多次。 所以“3s 5s 6h”也是有效的,并且应该导致:
(6 * 60 * 60) + (3 + 5) = 21608
秒
当您用相应的因子替换字母时,您可以将其通过管道传输到
bc
。您只需要处理该行末尾的+
即可。
t2s() {
sed 's/d/*24*3600 +/g; s/h/*3600 +/g; s/m/*60 +/g; s/s/\+/g; s/+[ ]*$//g' <<< "$1" | bc
}
试运行
$ t2s "3d 7h 5m 10s"
284710
$ t2s "3d 7h 5m "
284700
$ t2s "3s 5s 6h"
21608
我不知道是否有适合您要求的预定义命令,但我使用 GNU
grep
、paste
和 bc
想出了一个更紧凑且无循环的脚本。
使用示例,假设脚本保存为
t2sec
:
t2sec 3s
打印3
。t2sec "2m 1s"
、t2sec "1s 2m"
、t2sec "1m 1s 1m"
全部打印121
。t2sec "1s 2s"
、t2sec "1s2s"
、t2sec 1s 2s
、t2sec " 1s 2s "
全部打印3
。t2sec
、t2sec ""
、t2sec "1x"
、t2sec "s"
均不打印任何内容并以状态 1 退出。#! /bin/bash
t="$*"
# validate
grep -Pqx '( *\d+[smhd])+ *' <<< "$t" || exit 1
# helper functions
sumAndMultiply() { bc <<< "(0$(paste -s -d+))*$1"; }
xToSeconds() { grep -Po "\\d+(?=$1)" | sumAndMultiply "$2"; }
# convert to seconds
(
xToSeconds s 1 <<< "$t";
xToSeconds m 60 <<< "$t";
xToSeconds h 3600 <<< "$t";
xToSeconds d 86400 <<< "$t";
) | sumAndMultiply 1
基于 bash 函数的解决方案,支持天、小时、分钟和秒。
文件
sleepTimeToSeconds
:
#!/bin/bash
# Converts a time string like "2h 3m 3s" to the amount of seconds
function timeToSeconds() {
timeStr="$@"
# validate
grep -Pqx '( *\d+[smhd] +)+' <<< "$timeStr "
if [ $? != 0 ]
then
>&2 echo "error: Bad time format"
exit 1
fi
secs=0
for timePart in $timeStr
do
timeType=${timePart//[[:digit:]]/}
timeAmount=${timePart//[[:alpha:]]/}
toSecsFactor=0
case "$timeType" in
s|'')
toSecsFactor=1
;;
m)
toSecsFactor=60
;;
h)
let toSecsFactor="60 * 60"
;;
d)
let toSecsFactor="60 * 60 * 24"
;;
*)
>&2 echo "Bad time string type: '$timeType'"
exit 2
;;
esac
let secs="$secs + ( $timeAmount * $toSecsFactor )"
done
echo -n $secs
}
timeToSeconds "$@"
测试:
> sleepTimeToSeconds "5s 4s 1d 2h 3m"
93789
在极少数情况下,您没有
bc
可用:
(也许像我一样遭受 bash-on-Windows 的困扰?)
然后@WalterA函数
t2s
可以改成这样:
t2s() {
eq=$(sed 's/d/*24*3600 +/g; s/h/*3600 +/g; s/m/*60 +/g; s/s/\+/g; s/+[ ]*$//g' <<< "$1")
((val=eq))
echo "$val"
}
关于这个问题的Walter A 答案可以得到加强。
为了与 Mac OS 和其他平台兼容,最好为 sed 启用 ERE 模式(-E 标志)。启用 ERE 后,我们应该始终在规则的正则表达式部分中转义加号(请参阅此处)。另外,我们不需要在规则的替换部分中转义加号。
所以,这是固定的
t2s
bash 函数:
t2s() {
sed -E 's/d/*24*3600 +/g; s/h/*3600 +/g; s/m/*60 +/g; s/s/+/g; s/\+[ ]*$//g' <<< "$1" | bc
}
测试:
$ t2s "60m"
3600
$ t2s "1h50m50s"
6650