2016-12-19 2 views
0

Использование BASH Я хочу, чтобы цикл от начала до конца с десятиминутными интервалами. Я попыталсяBASH looping while time

begin_date="2015-01-01 00:00:00" 
end_date="2015-02-20 00:00:00" 
d=$begin_date 
while [ "$d" != "$end_date" ]; do 
    echo $d 
    d=$(date -d "${d} + 10 min" +"%Y-%m-%d %H:%M") 
done 

Но это не сработало. Глядя на Bash:Looping thru dates

#This works 
d=$(date -I -d "${d} + 1 day") 

#This doesn't work 
d=$(date -d "${d} + 1 day" +"%Y-%m-%d") 

Что я отсутствующей в строке формата?

+0

определить, что «это не сработало». Какой результат он производит? – fedorqui

+0

Он не добавил десять минут или день. – Miles

+0

Вопрос, на который вы ссылаетесь, специально объясняет, почему «-I» важен, но вы все равно его приняли. – tripleee

ответ

1

Пример вы связаны просто нужно быть немного изменены:

#!/bin/bash 

## User-specified dates. 
# See [GNU Coreutils: Date] for more info 
# [GNU Coreutils: Date]: https://www.gnu.org/software/coreutils/manual/html_node/Combined-date-and-time-of-day-items.html#Combined-date-and-time-of-day-items 
begin_date="2015-01-01T00:00" 
end_date="2015-01-01T00:40" 

# Run through `date` to ensure iso-8601 consistency 
startdate=$(date --iso-8601='minutes' --date="${begin_date}") 
enddate=$(date --iso-8601='minutes' --date="${end_date}") 

# Do loop 
d="$startdate" 
while [ "$d" != "$enddate" ]; do 
    echo $d 
    d=$(date --iso-8601='minutes' --date="$d + 10 minutes") 
done 

Обратите внимание, что опции -I и -d эквивалентны --iso-8601 и --date соответственно.

+0

Спасибо, Сигве, ваш ответ тоже работает. Не уверен, могу ли я поставить несколько ответов как правильно. – Miles

+0

Что касается дальнейшего тестирования, я перехожу к ответу Сигве. Я запустил оба метода в течение месяца. Sigve слегка быстрее был (хотя и не намного) @ реального 1m1.310s tripleee в 0m1.156s пользователя систа 0m55.953s против Sigve реально 0m57.308suser 0m0.953s SYS 0m52.250s Однако, почему я изменил ответ было то, что мне нужны четыре переменные, полученные из даты (старый/новый путь (YYYYMMDD) и старое/новое имя foo_HHMM), а приведенный выше код был легко переформатировать дату, тогда как другого кода не было. – Miles

+1

Незначительная коррекция для начала и окончания дат. Не используйте Z (т. Е. UTC). 'code' begin_date =" 2015-01-01T00: 00 " end_date =" 2015-01-01T00: 40 " ' code' – Miles

2

Выражение date -d "${d} + 10 min", похоже, не производит дату со смещением 10 минут. Фактически, когда я запускаю ваш код, я вижу счетчик даты, идущий назад. (Проводка этой диагностики в рамках вашего вопроса помогла бы другим узнать, где проблема: вам не нужно требовать, чтобы другие использовали ваш код, чтобы посмотреть, что он делает.)

В любом случае, разумный способ сделать это конвертируйте даты в Unix epoch, затем оттуда оттуда.

for ((d=$(date -d "$begin_date" +%s); d <= $(date -d "$end_date" +%s); d += 600)) 
do 
    date -d @$d +"%F %H:%M" 
done 

Выполнение арифметики даты в оболочке, вероятно, будет довольно неэффективным; преобразование этого, например, Awk или Perl могут стоить вашего времени, если вы считаете, что это слишком вяло или нужно запускать его много раз.

+0

Спасибо, код работает отлично. Борьба с этим около 8 часов! Мне нужно было время в google, чтобы понять ваш ответ :-) – Miles

+0

Спасибо за отзыв; добавлена ​​ссылка в Википедии. – tripleee

+0

Я также испытал эту редкую ошибку времени, обращаясь назад, говоря «+10 мин». – fedorqui