Script BASH: descargando archivos numerados consecutivos con wget
Pregunta
Tengo un servidor web que guarda los archivos de registro de una aplicación web numerada. Un ejemplo de nombre de archivo para esto sería:
dbsclog01s001.log
dbsclog01s002.log
dbsclog01s003.log
Los últimos 3 dígitos son el contador y pueden llegar hasta 100.
Normalmente abro un navegador web, busco el archivo como:
http://someaddress.com/logs/dbsclog01s001.log
y guarde los archivos. Por supuesto, esto se vuelve un poco molesto cuando obtienes 50 registros. Traté de crear un script BASH para usar wget y pasar
http://someaddress.com/logs/dbsclog01s*.log
pero estoy teniendo problemas con mi script. De todos modos, ¿alguien tiene una muestra de cómo hacer esto?
¡gracias!
Solución
#!/bin/sh
if [ $# -lt 3 ]; then
echo "Usage: $ ./seq_wget http://someaddress.com/logs/dbsclog01s%03d.log 1 50
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- "$@"
Guarde lo anterior como seq_wget
, dele permiso de ejecución ( chmod + x seq_wget
) y luego ejecute, por ejemplo:
$ wget http://someaddress.com/logs/dbsclog01s{001..050}.log
O, si tiene Bash 4.0, puede escribir
<*> O, si tiene curl
en lugar de wget
, puede seguir la respuesta de Dennis Williamson.
Otros consejos
curl
parece admitir rangos. Desde la página 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
Es posible que haya notado que dice "con ceros a la izquierda"
Puede usar secuencias de tipo echo en la URL de wget para descargar una cadena de números ...
wget http://someaddress.com/logs/dbsclog01s00{1..3}.log
Esto también funciona con letras
{a..z} {A..Z}
Puede usar una combinación de a for loop i n bash with el printf (por supuesto, modificar echo
a wget
según sea necesario):
$ 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
No estoy seguro exactamente qué problemas estaba experimentando, pero parece que un simple bucle en bash lo haría por usted.
for i in {1..999}; do
wget -k http://someaddress.com/logs/dbsclog01s$i.log -O your_local_output_dir_$i;
done
Tarea interesante, así que escribí un script completo para usted (combiné varias respuestas y más). Aquí está:
#!/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
Al comienzo de la secuencia de comandos, puede establecer la URL, el prefijo y el sufijo del archivo de registro, cuántos dígitos tiene en la parte de numeración y el directorio de descarga. Loop descargará todos los archivos de registro que encontró y saldrá automáticamente en el primer no existente (usando el tiempo de espera de wget).
Tenga en cuenta que este script asume que la indexación del archivo de registro comienza con 1, no con cero, como mencionó en el ejemplo.
Espero que esto ayude.
Aquí puede encontrar un script de Perl que se parece a lo que quiere
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");
}
Acabo de echar un vistazo a la discusión de la página de manual de wget sobre 'globbing':
De manera predeterminada, el globbing se activará si la URL contiene un carácter globbing. Esta opción se puede usar para activar o desactivar el bloqueo de forma permanente. Es posible que deba citar la URL para evitar que su shell la expanda. Globbing hace que Wget busque una lista de directorios, que es específica del sistema. Esta es la razón por la que actualmente solo funciona con servidores FTP de Unix (y los que emulan la salida de Unix "ls").
Así que wget http: // ... no funcionará con globbing.
Verifique si su sistema tiene seq, entonces sería fácil:
for i in $(seq -f "%03g" 1 10); do wget "http://.../dbsclog${i}.log"; done
Si su sistema tiene el comando jot en lugar de seq:
for i in $(jot -w "http://.../dbsclog%03d.log" 10); do wget $i; done
¡Oh! Este es un problema similar que encontré al aprender bash para automatizar las descargas de manga.
Algo como esto debería funcionar:
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
hecho
Tarde para la fiesta, pero una solución realmente fácil que no requiere codificación es usar el complemento DownThemAll Firefox, que tiene la funcionalidad para recuperar rangos de archivos. Esa fue mi solución cuando necesitaba descargar 800 archivos numerados consecutivamente.