如何将睡眠格式的时间段字符串转换为bash中的秒数

时间:2018-05-20 09:56:44

标签: bash parsing time

这是关于通用linux命令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

4 个答案:

答案 0 :(得分:2)

使用相应的因子替换字母时,可以将其传递给bc。您只需要处理行尾的+

t2s() {
   sed 's/d/*24*3600 +/g; s/h/*3600 +/g; s/m/*60 +/g; s/s/\+/g; s/+[ ]*$//g' <<< "$1" | bc
}

Testrun

$ t2s "3d 7h 5m 10s"
284710
$ t2s "3d 7h 5m "
284700
$ t2s "3s 5s 6h"
21608

答案 1 :(得分: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

答案 2 :(得分:1)

我不知道是否有符合您要求的预定义命令,但我使用GNU greppaste和{我想出了一个更紧凑且无循环的脚本{1}}。

用法示例,假设脚本保存为bc

  • t2sec打印t2sec 3s
  • 3t2sec "2m 1s"t2sec "1s 2m"全部打印t2sec "1m 1s 1m"
  • 121t2sec "1s 2s"t2sec "1s2s"t2sec 1s 2s全部打印t2sec " 1s 2s "
  • 3t2sect2sec ""t2sec "1x"全部不打印,退出状态为1。
t2sec "s"

答案 3 :(得分:1)

在极少数情况下,您没有bc可用: (也许像我一样遭受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"
}