Циклическое значение часа в unix - PullRequest
0 голосов
/ 08 октября 2018

У меня переменная даты в формате ггггммддч.Я пытаюсь перебрать элемент часа в нем.Я пробовал ниже путь, но он не может произвести вывод.

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 голосов
/ 08 октября 2018

Я думаю, что лучше указывать только даты 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

Живой пример доступен в учебная точка .

0 голосов
/ 08 октября 2018

Немного поигравшись с командой 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

Хотя я действительно считаю, что «лучше всего указывать даты в формате GNU только в формате ГГГГ-мм-дд ЧЧ-ММ-СС»«Совет @Kamil Cuk - это путь.

0 голосов
/ 08 октября 2018

Это работает, если вы поменяете местами + и -d: date -d '2018100602 + 1 hour' '+%Y%m%d%H', плюс он считает 2018100600 недопустимой датой.Но это работает, как ни странно:

now='20181006 00'
end='20181008 04'
until [[ $now == $end ]]; do
    now=$(date -d "${now} + 1 hour" '+%Y%m%d %H');
    echo $now
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...