在Unix中循环小时值

时间:2018-10-08 10:06:27

标签: shell unix awk

我有格式为yyyymmddhh的日期变量。我试图遍历其中的小时元素。我尝试下面的方法,但是无法产生输出。

now=2018100600
end=2018100804
while [ "$now" != "$end" ] ;
do
        now=`date +"%Y%m%d%H" -d "$now + 1 hour"`;
        echo $now
done

上述脚本的预期输出为2018100601,2018100602,... 2018100804

我的日期错误:invalid date ‘-53382311010101 + 1 hour'

有人可以帮我吗?预先感谢。

3 个答案:

答案 0 :(得分:1)

如果您将$title = $products[$_GET["ID"]]["Title"]; +交换为-d,那么它会起作用,而且它认为date -d '2018100602 + 1 hour' '+%Y%m%d%H'不是有效日期。但这很奇怪:

2018100600

答案 1 :(得分:1)

我认为最好只给GNU日期YYYY-mm-dd HH-MM-SS格式的日期。他不断误解输入日期格式。如果您有openbsd日期版本(我喜欢),则可以指定输入字符串字段。

这有效:

now=2018100600
end=2018100604
while (( now < end )); do
        now=$(
            date --date="${now:0:4}-${now:4:2}-${now:6:2} ${now:8:2}:00:00 +hour" +%Y%02m%02d%02H
        )
        echo "$now"
done

但是我仍然觉得使用时间戳更安全:

now_timestamp=$(date --date="${now:0:4}-${now:4:2}-${now:6:2} ${now:8:2}:00:00" +%s)
end_timestamp=$(date --date="${end:0:4}-${end:4:2}-${end:6:2} ${end:8:2}:00:00" +%s)
for ((i = now_timestamp; i < end_timestamp; i += 60 * 60)); do
    now=$(date --date="@$i" +%Y%02m%02d%02H)
    echo "$now"
done

可通过tutorialpoint获得实时示例。

答案 2 :(得分:0)

在稍微使用date命令之后,我找到了下面的解决方案。您希望通过-d切换来指定日期,date却不能解释为yyyymmddhh

因此,这是具有手动日期解析的解决方案。

#!/bin/sh

now=2018100600
end=2018100604

nowY=$(expr "$now" : "\([[:digit:]]\{4\}\)")
nowM=$(expr "$now" : "[[:digit:]]\{4\}\([[:digit:]]\{2\}\)")
nowD=$(expr "$now" : "[[:digit:]]\{4\}[[:digit:]]\{2\}\([[:digit:]]\{2\}\)")
nowH=$(expr "$now" : "[[:digit:]]\{4\}[[:digit:]]\{2\}[[:digit:]]\{2\}\([[:digit:]]\{2\}\)")

h_counter="$nowH"
((h_counter++))
date_runner=""
while true ; do
    date_runner=$(date -d "$nowY$nowM$nowD + $h_counter hours" +"%Y%m%d%H")
    echo $date_runner
    ((h_counter++))
    [ "$date_runner" == "$end" ] && break
done

尽管我确实认为@Kamil Cuk的建议是“最好给GNU日期仅以YYYY-mm-dd HH-MM-SS格式的日期”。