【发布时间】:2011-01-12 00:12:19
【问题描述】:
使用 Bash 脚本将 00:20:40.28 (HH:MM:SS) 转换为秒的简单方法是什么?
分秒可以删减,不是必须的。
【问题讨论】:
使用 Bash 脚本将 00:20:40.28 (HH:MM:SS) 转换为秒的简单方法是什么?
分秒可以删减,不是必须的。
【问题讨论】:
试试awk。作为奖励,您可以保持分秒。
echo "00:20:40.25" | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'
【讨论】:
echo "00:20:40.25" | awk -F: '{ print $1 + ($2/60) + ($3/3600) }'
即使您不指定小时或分钟,这也会起作用:echo "04:20:40" | sed -E 's/(.*):(.+):(.+)/\1*3600+\2*60+\3/;s/(.+):(.+)/\1*60+\2/' | bc
【讨论】:
试试这个:
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
($IFS) 拆分
${
$(()) 执行算术表达式。
希望这会有所帮助。
【讨论】:
IFS=":." 和 Seconds=$(( ... ))${Time[3]}
使用 GNU 日期,如果持续时间少于 24 小时,您可以通过将其视为纪元的一天中的时间来执行转换:
to_seconds() {
local epoch=$(date --utc -d @0 +%F)
date --utc -d "$epoch $1" +%s.%09N
}
使用问题中的示例运行它:
$ to_seconds 00:20:40.29
1240.290000000
请注意,--utc、@、%s 和 %N 都是 GNU 扩展,其他实现不一定支持。
【讨论】:
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
【讨论】:
如果您正在处理来自ps 的时间,请注意2-18:01 的格式也可以用于 2 天 19 小时 1 分钟。在这种情况下,您需要结帐:Parse ps' "etime" output and convert it into seconds
【讨论】:
您可以使用bc 命令将分钟转换为小时、秒或分钟。
举例:
1000 秒需要多少分钟?
$ echo 'obase=60;1000' | bc
02 00
然后 -> 2 分钟
375 分钟需要多少小时?
$ echo 'obase=60;375'| bc
06 15
然后 -> 06h15
56 小时是多少天?
$ echo 'obase=24;56' | bc
02 08
然后是 02 天零 8 小时
bc with obase 是额外的!
【讨论】:
echo "obase=60;14777" | bc 04 01 17 (4 天 1 小时 17 分钟!)
如果你不知道你到底有什么 - SS、MM:SS 或 HH:MM:SS,比如在youtube-dl --get-duration 之后,那么 awk 魔法可能会很有用:
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
【讨论】:
echo 1:35:12.3 | awk -F\: '{ for(k=NF;k>0;k--) sum+=($k*(60^(NF-k))); print sum }' 给了5712.3
我没有对此进行测试,但我认为这就是您拆分字符串的方式。然后乘以适当的小时数和分钟数。
mytime=’00:20:40.28′
part1=${mytime%%:*}; rest=${mytime#*:}
part2=${rest%%:*}; rest=${rest#*:}
part3=${rest%%:*};
【讨论】:
带壳,
#!/bin/bash
d="00:20:40.28"
IFS=":"
set -- $d
hr=$(($1*3600))
min=$(($2*60))
sec=${3%.*}
echo "total secs: $((hr+min+sec))"
【讨论】:
09:08:40.28 和类似的失败。
我有这个旧的 shell 函数(/bin/sh 在 POSIX shell 的意义上兼容,而不是 bash),它在整数数学中进行这种转换(秒内没有小数):
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"
}
输出:
$ tim2sec 1:23:45.243
5025
它仅适用于 SS、MM:SS 和 HH:MM:SS :)
【讨论】:
TZ=utc date +'%s' -d "1970-01-01 00:00:38"
【讨论】:
我认为最简单的方法是从纪元时间算起:
$ date_var="00:20:40.28";
$ date +'%s.%3N' -d "1970-01-01 $date_var" --utc
1240.280
您还可以根据需要轻松更改格式。
【讨论】: