Сценарий BASH: загрузка последовательных пронумерованных файлов с помощью wget

У меня есть веб-сервер, который сохраняет файлы журналов веб-приложения с номером. Пример имени файла для этого:

dbsclog01s001.log
dbsclog01s002.log
dbsclog01s003.log

Последние 3 цифры являются счетчиком, и они могут доходить до 100.

Обычно я открываю веб-браузер, просматриваю файл, например:

http://someaddress.com/logs/dbsclog01s001.log

и сохраните файлы. Это, конечно, немного раздражает, когда вы получаете 50 журналов. Я попытался придумать скрипт BASH для использования wget и передачи

http://someaddress.com/logs/dbsclog01s*.log

но у меня проблемы с моим скриптом. Во всяком случае, у кого-нибудь есть образец того, как это сделать?

Благодарность!


person wonderer    schedule 15.09.2009    source источник
comment
* — это локальное расширение имени файла — оно работает только для файлов по текущему пути для вашей собственной машины. Вам придется перебрать все удаленные адреса.   -  person Fragsworth    schedule 15.09.2009


Ответы (11)


#!/bin/sh

if [ $# -lt 3 ]; then
        echo "Usage: $0 url_format seq_start seq_end [wget_args]"
        exit
fi

url_format=$1
seq_start=$2
seq_end=$3
shift 3

printf "$url_format\\n" `seq $seq_start $seq_end` | wget -i- "$@"

Сохраните приведенное выше как seq_wget, дайте ему разрешение на выполнение (chmod +x seq_wget), а затем запустите, например:

$ ./seq_wget http://someaddress.com/logs/dbsclog01s%03d.log 1 50

Или, если у вас Bash 4.0, вы можете просто ввести

$ wget http://someaddress.com/logs/dbsclog01s{001..050}.log

Или, если у вас есть curl вместо wget, вы можете следовать ответу Денниса Уильямсона.

person ephemient    schedule 15.09.2009
comment
ответ bash+wget должен быть ответом сам по себе. это самый простой и быстрый способ сделать это. - person endolith; 09.09.2013
comment
Подход wget someaddress.com/logs/dbsclog01s{001..050}.log работал у меня: Ubuntu 12.10 - person Yauhen; 16.02.2014

curl, кажется, поддерживает диапазоны. Со страницы man:

URL  
       The URL syntax is protocol dependent. You’ll find a  detailed  descrip‐
       tion in RFC 3986.

       You  can  specify  multiple  URLs or parts of URLs by writing part sets
       within braces as in:

        http://site.{one,two,three}.com

       or you can get sequences of alphanumeric series by using [] as in:

        ftp://ftp.numericals.com/file[1-100].txt
        ftp://ftp.numericals.com/file[001-100].txt    (with leading zeros)
        ftp://ftp.letters.com/file[a-z].txt

       No nesting of the sequences is supported at the moment, but you can use
       several ones next to each other:

        http://any.org/archive[1996-1999]/vol[1-4]/part{a,b,c}.html

       You  can  specify  any amount of URLs on the command line. They will be
       fetched in a sequential manner in the specified order.

       Since curl 7.15.1 you can also specify step counter for the ranges,  so
       that you can get every Nth number or letter:

        http://www.numericals.com/file[1-100:10].txt
        http://www.letters.com/file[a-z:2].txt

Возможно, вы заметили, что здесь написано «с ведущими нулями»!

person Dennis Williamson    schedule 15.09.2009
comment
Вы также можете ссылаться на последовательности curl http://example.com/logs/dbsclog01s[001-100].log -o log#1.log - person Mike Almond; 10.12.2013
comment
Лучший ответ. Приятно копать! - person Giacomo1968; 12.01.2017

Вы можете использовать последовательности типа эха в URL-адресе wget для загрузки строки чисел...

wget http://someaddress.com/logs/dbsclog01s00{1..3}.log

Это также работает с буквами

{a..z} {A..Z}

person Stephan    schedule 04.01.2016
comment
Любая идея, как указать последовательность типа эха через параметры скрипта? - person Alex Zubkov; 02.04.2021
comment
Не уверен, что вы могли бы сделать это с помощью wget, я знаю, что это работает с curl curl http://someaddress.com/logs/dbsclog01s00[1-${variable}].log - person Stephan; 04.04.2021

Не знаю точно, с какими проблемами вы столкнулись, но похоже, что простой цикл for в bash сделает это за вас.

for i in {1..999}; do
wget -k http://someaddress.com/logs/dbsclog01s$i.log -O your_local_output_dir_$i;
done
person anschauung    schedule 15.09.2009
comment
Конечно, вы захотите заменить «999» на фактическое количество файлов или, возможно, добавить некоторую логику для их предварительного подсчета. Входные и выходные строки также могут нуждаться в некоторой доработке, в зависимости от того, как выглядит настоящий URL-адрес. - person anschauung; 15.09.2009
comment
моя проблема заключалась в том, чтобы превратить что-то похожее на то, что вы только что написали, в скрипт, который может принимать URL-адрес и имя файла в качестве аргументов. - person wonderer; 15.09.2009
comment
Ах! Итак, вы ищете что-то вроде небольшой утилиты bash, которая будет принимать литерал URL, литерал выходного файла и количество файлов, а затем запускать цикл wget на основе этой информации? $0, $1, $2 и т. д. — это входные аргументы в сценариях bash, поэтому я мог бы изменить пример, чтобы отразить это, если вы подтвердите, что это то, что вы ищете. - person anschauung; 15.09.2009
comment
В диапазоне {1..999} должно быть только две точки. - person Dennis Williamson; 15.09.2009

Вы можете использовать комбинацию цикла for иn bash с printf (конечно, изменяя echo на wget по мере необходимости):

$ for i in {1..10}; do echo "http://www.com/myurl`printf "%03d" $i`.html"; done
http://www.com/myurl001.html
http://www.com/myurl002.html
http://www.com/myurl003.html
http://www.com/myurl004.html
http://www.com/myurl005.html
http://www.com/myurl006.html
http://www.com/myurl007.html
http://www.com/myurl008.html
http://www.com/myurl009.html
http://www.com/myurl010.html
person Mark Rushakoff    schedule 15.09.2009
comment
Спасибо. Как я могу превратить вещь в полный скрипт, который принимает URL-адрес в качестве аргумента? - person wonderer; 15.09.2009

Интересная задача, поэтому я написал для вас полный сценарий (объединил несколько ответов и многое другое). Вот:

#!/bin/bash
# fixed vars
URL=http://domain.com/logs/     # URL address 'till logfile name
PREF=logprefix                  # logfile prefix (before number)
POSTF=.log                      # logfile suffix (after number)
DIGITS=3                        # how many digits logfile's number have
DLDIR=~/Downloads               # download directory
TOUT=5                          # timeout for quit
# code
for((i=1;i<10**$DIGITS;++i))
do
        file=$PREF`printf "%0${DIGITS}d" $i`$POSTF   # local file name
        dl=$URL$file                                 # full URL to download    
        echo "$dl -> $DLDIR/$file"                   # monitoring, can be commented
        wget -T $TOUT -q $dl -O $file
        if [ "$?" -ne 0 ]                            # test if we finished
        then
                exit
        fi
done

В начале скрипта вы можете указать URL, префикс и суффикс файла журнала, сколько цифр у вас есть в части нумерации и каталог загрузки. Loop загрузит все найденные файлы журнала и автоматически завершится при первом несуществующем (используя тайм-аут wget).

Обратите внимание, что этот сценарий предполагает, что индексация файла журнала начинается с 1, а не с нуля, как вы упомянули в примере.

Надеюсь это поможет.

person igustin    schedule 15.09.2009
comment
Спасибо. Я получаю сообщение: не найдена ошибка. а затем, поскольку max не определено, после этого я получаю сообщение об ошибке в строке. - person wonderer; 15.09.2009
comment
Хм, очевидно, у вас какая-то другая версия bash. :-( Хорошо, я изменил сценарий, чтобы использовать не let, а прямое выражение в цикле for. Попробуйте сейчас и дайте мне знать. - person igustin; 15.09.2009

Здесь вы можете найти сценарий Perl, который выглядит так, как вы хотите.

http://osix.net/modules/article/?id=677

#!/usr/bin/perl
$program="wget"; #change this to proz if you have it ;-)
my $count=1; #the lesson number starts from 1
my $base_url= "http://www.und.nodak.edu/org/crypto/crypto/lanaki.crypt.class/lessons/lesson";
my $format=".zip"; #the format of the file to download
my $max=24; #the total number of files to download
my $url;

for($count=1;$count<=$max;$count++) {
    if($count<10) {
    $url=$base_url."0".$count.$format; #insert a '0' and form the URL
    }
    else {
    $url=$base_url.$count.$format; #no need to insert a zero
    }
    system("$program $url");
}
person Carlos Tasada    schedule 15.09.2009

Я только что посмотрел на странице руководства wget обсуждение «подстановки»:

По умолчанию подстановка будет включена, если URL-адрес содержит символ подстановки. Эта опция может использоваться для постоянного включения или выключения подстановки. Возможно, вам придется указать URL-адрес в кавычках, чтобы защитить его от расширения вашей оболочкой. Подстановка заставляет Wget искать список каталогов, который зависит от системы. Поэтому в настоящее время он работает только с FTP-серверами Unix (и теми, которые эмулируют вывод Unix "ls").

Так что wget http://... не будет работать с подстановкой.

person pavium    schedule 15.09.2009

Проверьте, есть ли в вашей системе seq, тогда это будет легко:

for i in $(seq -f "%03g" 1 10); do wget "http://.../dbsclog${i}.log"; done

Если в вашей системе есть команда jot вместо seq:

for i in $(jot -w "http://.../dbsclog%03d.log" 10); do wget $i; done
person Hai Vu    schedule 15.09.2009

Ой! это аналогичная проблема, с которой я столкнулся, изучая bash для автоматизации загрузки манги.

Что-то вроде этого должно работать:

for a in `seq 1 999`; do
if [ ${#a} -eq 1 ]; then
    b="00"
elif [ ${#a} -eq 2 ]; then
    b="0"
fi
echo "$a of 231"
wget -q http://site.com/path/fileprefix$b$a.jpg

Выполнено

person Doug A.K.    schedule 05.01.2011
comment
В некоторых случаях вам может понадобиться много операторов if (или оператора case). Или вы можете использовать что-то вроде этого: b=000; for a in 1 10 100 1000; do echo "${b:${#a}-1}$a"; done - person Dennis Williamson; 29.01.2012

Поздно на вечеринку, но действительно простое решение, не требующее кодирования, — это использовать надстройку DownThemAll для Firefox, которая имеет функциональность для извлечения диапазонов файлов. Это было моим решением, когда мне нужно было загрузить 800 последовательно пронумерованных файлов.

person Kc Daugirdas    schedule 28.04.2017