首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Foreach hour:min:sec.ms

Foreach hour:min:sec.ms
EN

Stack Overflow用户
提问于 2021-09-29 20:03:47
回答 2查看 82关注 0票数 0

我想知道如何解析指定小时、分钟、秒和毫秒的foreach。就像这样:

代码语言:javascript
复制
DURATION=00:14:17.82 // (00 hours, 14 minutes, 17 seconds and 82ms)
for ((i=1;i<=DURATION;i++)); do
    // output the hour, minute, second and ms here
done

我想迭代每毫秒,秒,分钟,小时!如下所示:

代码语言:javascript
复制
00:14:17.82
00:14:17.83
00:14:17.84
00:14:17.85
...
00:14:18.01
00:14:18.02
...
01:00:10.15
01:00:10.16
01:00:10.17
...

我只知道创造这几秒钟和仅仅几秒钟!但是,我怎样才能做几个小时、几分钟、几秒和几秒呢?非常感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-29 21:33:05

注意:下面的想法假设为23:59:59:9924:00:00.00的最大DURATION;上限范围当然可以增加,但请记住用于大括号扩展的额外开销(cpu和/或内存),特别是如果生成巨大的范围使DURATION相形见绌(即生成大量的时间戳,您将永远不会处理)。

如果要手动输入DURATION的值,则可以手动输入以下大括号扩展系列:

代码语言:javascript
复制
for i in {00..00}:{00..14}:{00..17}.{00..82}
do
    echo $i
done

注意:这组相对较小的支撑扩展几乎是瞬时的,在我的系统上占用了~6MB(内存)。

这就产生了:

代码语言:javascript
复制
00:00:00.00
00:00:00.01
00:00:00.02
00:00:00.03
00:00:00.04
... snip ...
00:14:17.78
00:14:17.79
00:14:17.80
00:14:17.81
00:14:17.82

另一种选择是:

代码语言:javascript
复制
DURATION=00:14:17.82

for i in {00..23}:{00..59}:{00..59}.{00..99}
do
    [[ "${i}" > "${DURATION}" ]] && break
    # do other stuff
done

注:

在我的系统中,这大约花费了10秒和1.6GB(内存)来扩展大括号扩展的系列,在processed

  • this之前,循环是,特定的大括号扩展创建了864万个时间戳,但是.
  • ,我们在处理了86K时间戳(或大括号扩展产生的时间戳的1%)之后,突破了循环,所以.
  • 我们浪费了大量的e 225的周期和内存产生的时间戳,而我们从未使用H 226>

另一个想法是编写一组4深的for循环,并在我们访问00:14:17.82之后爆发出来,例如:

代码语言:javascript
复制
DURATION='00:14:17.82'

for a in {00..23}; do
    for b in {00..59}; do
        for c in {00..59}; do
            for d in {00..99}; do
                [[ "${a}:${b}:${c}.${d}" > "${DURATION}" ]] && break 4
                # do other stuff here
            done
        done
    done
done

注意:虽然每个大括号扩展都很快(并且使用的内存数量很小),嵌套/重复扩展将占用大量时间才能到达${DURATION};但是,与前面的想法不同的是,这个扩展至少会让您立即开始处理时间戳值,在执行新的支撑扩展时会出现间歇性(短暂)延迟。

当然,我们可以跳过支撑扩展开销,使用“正常”for循环,例如:

代码语言:javascript
复制
DURATION='00:14:17.82'

for ((a=0; a<=23; a++)); do
    for ((b=0; b<=59; b++)); do
       for ((c=0; c<=59; c++)); do
           for ((d=0; d<=99; d++)); do
                printf -v ts "%02d:%02d:%02d.%02d" ${a} ${b} ${c} ${d}
                [[ "${ts}" > "${DURATION}" ]] && break 4
                # do other stuff here
           done
       done
    done
done

备注:

这消除了支撑expansions

  • assumes的cpu/time/RAM开销,您有一个支持printf -v

的较新版本的bash

对于受虐者来说:

代码语言:javascript
复制
DURATION='00:14:17.82'

for ((i=0; i<8640000; i++)); do

      hr=$(( ( i / 100 / 60 / 60 ) %  24 ))
     min=$(( ( i / 100 / 60 )      %  60 ))
     sec=$(( ( i / 100 )           %  60 ))
    msec=$((   i                   % 100 ))

    printf -v ts "%02d:%02d:%02d.%02d" ${hr} ${min} ${sec} ${msec}
    [[ "${ts}" > "${DURATION}" ]] && break
    # do other stuff
done
票数 1
EN

Stack Overflow用户

发布于 2021-09-30 00:12:05

只需在毫秒内迭代并在使用时转换为您想要的表示。首先,我们编写转换函数:

代码语言:javascript
复制
millis_to_human() {
   local h m s ms
   # calculate all those hours, minutes, seconds...
   ((
      ms = $1,
      s = ms / 100,
      ms %= 100,
      m = s / 60,
      s %= 60,
      h = m / 60,
      h %= 60,
      1
   ))
   printf "%02d:%02d:%02d.%02d\n" "$h" "$m" "$s" "$ms"
}
human_to_millis() {
   # Match with regex
   [[ $1 =~ ([0-9]*):([0-9]*):([0-9]*).([0-9]*) ]]
   # Using 10# so that the number is always in base 10, even with leading 0.
   echo $(( ( (
      10#${BASH_REMATCH[1]} * 60 +
      10#${BASH_REMATCH[2]} ) * 60 +
      10#${BASH_REMATCH[3]} ) * 100 +
      10#${BASH_REMATCH[4]} ))
}

然后就是:

代码语言:javascript
复制
duration='00:14:17.82'
duration_ms=$(human_to_millis "$duration")
for ((i = 1; i <= duration_ms; ++i)); do
   millis_to_human "$i"
done
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69382726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档