Как сгенерировать список всех дат в диапазоне с помощью инструментов, доступных в bash?

Я хочу загрузить кучу файлов с именами ISO-8601. Есть ли простой способ сделать это с помощью bash + GNU coreutils? (Или некоторый трюк, чтобы wget/curl автоматически сгенерировал список, но я нахожу это маловероятным)

Подобно этому вопросу, но не ограничивается будними днями: Как создать диапазон дат без ожидания с помощью инструментов, доступных в bash?. Я предполагаю, что есть более простой способ сделать это без этого ограничения.

Также относится к Как создать диапазон дат для случайных данных в bash, но не ограничивается одним годом.

Ответ 1

Если у вас есть date GNU, вы можете использовать любой цикл for в любой POSIX-совместимой оболочке:

# with "for"
for i in {1..5}; do 
    echo $(date -I -d "2014-06-28 +$i days")
done

или цикл until, на этот раз с использованием расширенного теста Bash [[:

# with "until"
d="2014-06-29"
until [[ $d > 2014-07-03 ]]; do 
    echo "$d"
    d=$(date -I -d "$d + 1 day")
done

Обратите внимание, что не древние версии sh также будут выполнять лексикографическое сравнение, если вы измените условие на [ "$d" \> 2014-07-03 ].

Вывод из любого из этих циклов:

2014-06-29
2014-06-30
2014-07-01
2014-07-02
2014-07-03

Для более переносимого способа сделать то же самое, вы можете использовать Perl-скрипт:

use strict;
use warnings;
use Time::Piece;
use Time::Seconds;    
use File::Fetch;

my ($t, $end) = map { Time::Piece->strptime($_, "%Y-%m-%d") } @ARGV; 

while ($t <= $end) {
    my $url = "http://www.example.com/" . $t->strftime("%F") . ".log";
    my $ff = File::Fetch->new( uri => $url );
    my $where = $ff->fetch( to => '.' );  # download to current directory
    $t += ONE_DAY;
}

Time :: Piece, Time :: Seconds и File :: Fetch являются основными модулями. Используйте его как perl wget.pl 2014-06-29 2014-07-03.

Ответ 2

Используя GNU date и bash:

start=2014-12-29
end=2015-01-03
while ! [[ $start > $end ]]; do
    echo $start
    start=$(date -d "$start + 1 day" +%F)
done
2014-12-29
2014-12-30
2014-12-31
2015-01-01
2015-01-02
2015-01-03

Ответ 3

Вот как я это сделал:

d=$(date -I);
while wget "http://www.example.com/$d.log"; do
    d=$(date -I -d "$d - 1 day");
done

Это попытка загрузить все файлы с сегодняшнего дня, пока мы не получим 404.

Ответ 4

Я использую эту удобную функцию для работы с файлами журнала в формате yyyymmdd.log.gz:

function datelist { for dt in $(seq -w $1 $2) ; do date -d $dt +'%Y%m%d' 2>/dev/null ; done ; } 

Он принимает даты в формате yyyymmdd.