This is about a time string in the format accepted by the common linux command sleep
, like "3d 7h 5m 10s" (3 days, 7 hours, 5 minutes and 10 seconds), which would have to result in:
(3 * 24 * 60 * 60) + (7 * 60 * 60) + (5 * 60) + 10 = 284710
seconds
Note that not all these 4 elements must be present, nor in the right order, and one element might appear multiple times. So "3s 5s 6h" is valid too, and should result in:
(6 * 60 * 60) + (3 + 5) = 21608
seconds
When you replace the letters with the corresponding factors, you can pipe that to bc
. You only need to take care of the +
at the end of the line.
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
A bash function based solution that supports days, hours, minutes and seconds.
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
I don't know if there is a predefined command that fits your requirements, but I came up with a more compact and loop-free script using GNU grep
, paste
, and bc
.
Usage examples, assuming the script is saved as t2sec
:
t2sec 3s
prints 3
. t2sec "2m 1s"
, t2sec "1s 2m"
, t2sec "1m 1s 1m"
all print 121
. t2sec "1s 2s"
, t2sec "1s2s"
, t2sec 1s 2s
, t2sec " 1s 2s "
all print 3
. t2sec
, t2sec ""
, t2sec "1x"
, t2sec "s"
all print nothing and exit with status of 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
In the rare case you don't have bc
available: (perhaps bash-on-Windows like I suffer with?)
Then the @WalterA function t2s
can be changed to this:
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"
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.