Как передать диапазон дат через l oop в bash? - PullRequest
0 голосов
/ 02 марта 2020

Я новичок в Bash, поэтому, пожалуйста, помогите мне лучше сформулировать этот вопрос, если нужно.

Допустим, у меня есть сценарий .sh. Этот скрипт выполняет некоторые расчеты для некоторых данных за каждый день предыдущей недели с воскресенья по субботу (неделя начинается с воскресенья). Например, сегодня я запускаю этот сценарий для данных, начиная с 23 февраля 2020 года по 29 февраля 2020 года. При запуске сценария на моем терминале я предоставляю 3 параметра - год, месяц и день

./scriptname.sh ${yyyy} ${mm} ${dd}

Сейчас большинство времени у меня все хорошо с чем-то вроде этого

yyyy=2020; mm=02; for dd in seq 23 -w 29; do ./scriptname.sh ${yyyy} ${mm} ${dd}; done

Но почти каждый месяц есть неделя, которая распространяется на следующий месяц (например, неделя с 29 марта по 4 апреля). Сначала я подумал, что смогу немного автоматизировать это, используя переменные

start_day=$(date -d "last-sunday -7 days" +%d);
end_day=$(date -d "last-saturday" +%d);
start_month=$(date -d "last-sunday -7 days" +%m);
end_month=$(date -d "last-saturday" +%m);

Так что приведенный выше скрипт изменится на что-то вроде этого (пришлось исключить обратную галочку вокруг seq для форматирования ради)

yyyy=2020; for mm in  ${start_month} ${end_month}; do for dd in  seq -w ${start_day} ${end_day}; do ./scriptname.sh ${yyyy} ${mm} ${dd}; done; done

Но это создает все перестановки dd и mm. Как мне убедиться, что я передаю только эти 7 соответствующих значений для ${yyyy} ${mm} ${dd}?

2020 03 29
2020 03 30
2020 03 31
2020 04 01
2020 04 02
2020 04 03
2020 04 04

Ответы [ 2 ]

3 голосов
/ 02 марта 2020

Не делай этого сам. Даты хитрые, месяцы имеют различное количество дней и т. Д. c. Ваш сценарий также нуждается в дополнительной обработке лет. Пусть date обрабатывает вычисления с датами.

for i in {1..7}; do ./scriptname.sh $(date --date="-$i days" "+%Y %m %d"); done

.g неделя, проходящая с 29 марта по 4 апреля

То, как я бы это сделал, - это взять 29-й матч в количестве секунд с начала эпохи. Затем добавьте полдня, чтобы дополнительные секунды, если таковые имеются, не были проблемой. Затем просто увеличьте его на количество секунд в дне и используйте date для преобразования его обратно в дату.

then=$(date --date='2020/03/29 12:00:00' +%s);
for i in {0..6}; do 
     ./scriptname.sh $(date --date="@$((then + $i * 60 * 60 * 24))" "+%Y %m %d");
done

В качестве альтернативы, вы можете сделать это без переменной then, но вы должны помнить что число +0 сразу после даты интерпретируется как часовой пояс.

for i in {0..6}; do ./scriptname.sh $(date --date="2020/03/29 12:00:00 +0 +$i days" '+%Y %m %d'); done

Поскольку мне нравится потоковый анализ в bash, я бы проанализировал вывод с помощью xargs:

seq 6 | xargs -I{} date -d '2020/03/29 12:00:00Z +{} days' '+%Y %m %d' | xargs -n3 ./scriptname.sh
1 голос
/ 02 марта 2020

Другой пример, вычисление дней с использованием секунд:

for s in $(seq $(date -d "last-sunday -7 days" +%s) 86400 $(date -d "last-sunday" +%s)); do date --date=@$s "+%Y %m %d"; done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...