Quel est un moyen facile de convertir 00:20:40.28
(HH: MM: SS) en secondes avec un script Bash?
Des secondes peuvent être coupées, ce n’est pas essentiel.
Essayez awk
. En prime, vous pouvez garder les fraction de seconde.
echo "00:20:40.25" | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'
Essaye ça:
T='00:20:40.28'
SavedIFS="$IFS"
IFS=":."
Time=($T)
Seconds=$((${Time[0]}*3600 + ${Time[1]}*60 + ${Time[2]})).${Time[3]}
IFS="$SavedIFS"
echo $Seconds
($<string>) se divise <string> basé sur le séparateur (IFS
).
$ {<tableau>[<index>]} renvoie l'élément de la <tableau> au <index>.
$ ((<expression arithmétique>)) effectue l'expression arithmétique.
J'espère que cela t'aides.
Cela fonctionnerait même si vous ne spécifiez pas les heures ou les minutes: echo "04:20:40" | sed -E 's/(.*):(.+):(.+)/\1*3600+\2*60+\3/;s/(.+):(.+)/\1*60+\2/' | bc
Je n'ai pas testé cela mais, je pense que c'est comme ça que vous fendiez la chaîne. Suivi en multipliant par les quantités appropriées pour les heures et les minutes.
mytime=’00:20:40.28′
part1=${mytime%%:*}; rest=${mytime#*:}
part2=${rest%%:*}; rest=${rest#*:}
part3=${rest%%:*};
Si vous traitez une heure à partir de ps
, sachez que le format 2-18:01
est également possible pendant 2 jours, 19 heures, 1 minute. Dans ce cas, vous devrez vérifier: Analyser la sortie "etime" de ps et la convertir en secondes
avec la coquille,
#!/bin/bash
d="00:20:40.28"
IFS=":"
set -- $d
hr=$(($1*3600))
min=$(($2*60))
sec=${3%.*}
echo "total secs: $((hr+min+sec))"
echo "40.25" | awk -F: '{ if (NF == 1) {print $NF} else if (NF == 2) {print $1 * 60 + $2} else if (NF==3) {print $1 * 3600 + $2 * 60 + $3} }'
40.25
echo "10:40.25" | awk -F: '{ if (NF == 1) {print $NF} else if (NF == 2) {print $1 * 60 + $2} else if (NF==3) {print $1 * 3600 + $2 * 60 + $3} }'
640.25
echo "20:10:40.25" | awk -F: '{ if (NF == 1) {print $NF} else if (NF == 2) {print $1 * 60 + $2} else if (NF==3) {print $1 * 3600 + $2 * 60 + $3} }'
72640.25
Avec GNU date, vous pouvez effectuer la conversion si la durée est inférieure à 24 heures, en la considérant comme une heure de la journée:
to_seconds() {
local Epoch=$(date --utc -d @0 +%F)
date --utc -d "$Epoch $1" +%s.%09N
}
Le lancer avec l'exemple de la question:
$ to_seconds 00:20:40.29
1240.290000000
Notez que --utc
, @
, %s
et %N
sont tous des extensions GNU qui ne sont pas nécessairement prises en charge par d'autres implémentations.
Vous pouvez convertir des minutes en heure, secondes ou minutes avec la commande bc
.
Par exemple:
Combien de minutes pour 1000 secondes?
$ echo 'obase=60;1000' | bc
02 00
alors -> 2 min
Combien d'heures pour 375 min?
$ echo 'obase=60;375'| bc
06 15
alors -> 06h15
Comment jours pour 56 heures?
$ echo 'obase=24;56' | bc
02 08
puis 02 jours et 08 heures
bc avec obase c'est extra!
Si vous ne savez pas ce que vous avez exactement - SS, MM: SS ou HH: MM: SS, comme après youtube-dl --get-duration
, alors la magie awk pourrait être utile:
echo 12 | awk -F\: '{ for(k=NF;k>0;k--) sum+=($k*(60^(NF-k))); print sum }'
12
echo 35:12 | awk -F\: '{ for(k=NF;k>0;k--) sum+=($k*(60^(NF-k))); print sum }'
2112
echo 1:35:12 | awk -F\: '{ for(k=NF;k>0;k--) sum+=($k*(60^(NF-k))); print sum }'
5712
J'ai cette ancienne fonction Shell (/ bin/sh compatible au sens de POSIX Shell, pas bash) qui effectue cette conversion en maths entier (pas de fractions dans les secondes):
tim2sec() {
mult=1
arg="$1"
res=0
while [ ${#arg} -gt 0 ]; do
prev="${arg%:*}"
if [ "$prev" = "$arg" ]; then
curr="${arg#0}" # avoid interpreting as octal
prev=""
else
curr="${arg##*:}"
curr="${curr#0}" # avoid interpreting as octal
fi
curr="${curr%%.*}" # remove any fractional parts
res=$((res+curr*mult))
mult=$((mult*60))
arg="$prev"
done
echo "$res"
}
Les sorties:
$ tim2sec 1:23:45.243
5025
Cela fonctionne avec SS, MM: SS et HH: MM: SS uniquement :)