Как преобразовать строку периода времени в формате сна в секунды в Bash - PullRequest
0 голосов
/ 20 мая 2018

Это строка времени в формате, принятом обычной командой 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 секунд

Ответы [ 3 ]

0 голосов
/ 20 мая 2018

Я не знаю, есть ли предопределенная команда, которая соответствует вашим требованиям, но я придумал более компактный и беспериодный скрипт, использующий 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
0 голосов
/ 20 мая 2018

Когда вы заменяете буквы соответствующими коэффициентами, вы можете передать их на 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
0 голосов
/ 20 мая 2018

Решение на основе функции bash, которое поддерживает дни, часы, минуты и секунды.

file 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 "$@"

test:

> sleepTimeToSeconds "5s 4s 1d 2h 3m"
93789
...