Script BASH: Télécharger des fichiers numérotés consécutifs avec wget
Question
J'ai un serveur Web qui enregistre les fichiers journaux d'une application Web numérotée. Voici un exemple de nom de fichier:
dbsclog01s001.log
dbsclog01s002.log
dbsclog01s003.log
Les 3 derniers chiffres constituent le compteur et peuvent aller jusqu’à 100.
J'ouvre généralement un navigateur Web, accédez au fichier tel que:
http://someaddress.com/logs/dbsclog01s001.log
et enregistrez les fichiers. Cela devient évidemment un peu gênant lorsque vous obtenez 50 journaux. J'ai essayé de trouver un script BASH pour utiliser wget et passer
http://someaddress.com/logs/dbsclog01s*.log
mais j'ai des problèmes avec mon script. Quoi qu'il en soit, tout le monde a un exemple sur la façon de le faire?
merci!
La solution
#!/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- "$@"
Enregistrez ce qui précède sous seq_wget
, donnez-lui le droit d'exécution ( chmod + x seq_wget
), puis exécutez-le, par exemple:
$ wget http://someaddress.com/logs/dbsclog01s{001..050}.log
Ou, si vous avez Bash 4.0, vous pouvez simplement taper
<*> Si vous avez curl
au lieu de wget
, vous pouvez suivre la réponse de Dennis Williamson.
Autres conseils
curl
semble prendre en charge les plages. A partir de la page 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
Vous avez peut-être remarqué qu'il est indiqué "avec des zéros"!
Vous pouvez utiliser des séquences de type echo dans l'URL wget pour télécharger une chaîne de nombres ...
wget http://someaddress.com/logs/dbsclog01s00 {1..3} .log
Cela fonctionne aussi avec les lettres
{a..z} {A..Z}
Vous pouvez utiliser une combinaison de une boucle for i n bash avec la commande printf (bien sûr, modifier echo
en wget
au besoin):
$ 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
Vous ne savez pas exactement quels problèmes vous avez rencontré, mais cela ressemble à une simple boucle for le ferait pour vous.
for i in {1..999}; do
wget -k http://someaddress.com/logs/dbsclog01s$i.log -O your_local_output_dir_$i;
done
Tâche intéressante, j'ai donc écrit le script complet pour vous (plusieurs réponses et plus encore). La voici:
#!/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
Au début du script, vous pouvez définir l’URL, le préfixe et le suffixe du fichier journal, le nombre de chiffres que vous avez dans la partie numérotation et le répertoire de téléchargement. Loop téléchargera tous les fichiers de log trouvés, et se fermera automatiquement au premier non-existant (en utilisant le délai d'attente de wget).
Notez que ce script suppose que l'indexation du fichier journal commence par 1, et non par zéro, comme vous l'avez mentionné dans l'exemple.
J'espère que cela vous aidera.
Ici vous pouvez trouver un script Perl qui ressemble à ce que vous voulez
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");
}
Je viens de jeter un coup d’œil à la discussion de la page de manuel wget sur "globbing":
Par défaut, la suppression est activée si l'URL contient un caractère de suppression. Cette option peut être utilisée pour activer ou désactiver la navigation en permanence. Vous devrez peut-être citer l’URL pour éviter qu’elle ne soit développée par votre shell. Globbing permet à Wget de rechercher une liste de répertoires spécifique au système. C’est pourquoi il ne fonctionne actuellement que sur les serveurs FTP Unix (et ceux émulant la sortie "ls" Unix).
Donc wget http: // ... ne fonctionnera pas avec la suppression.
Vérifiez si votre système dispose de seq, alors ce serait facile:
for i in $(seq -f "%03g" 1 10); do wget "http://.../dbsclog${i}.log"; done
Si votre système utilise la commande jot au lieu de seq:
for i in $(jot -w "http://.../dbsclog%03d.log" 10); do wget $i; done
Oh! C’est un problème similaire que j’ai rencontré lors de l’apprentissage de Bash pour automatiser les téléchargements de manga.
Quelque chose comme ça devrait marcher:
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
terminé
En retard pour le parti, mais une solution simple et efficace ne nécessitant aucun codage consiste à utiliser le module complémentaire DownThemAll Firefox, qui permet de récupérer des plages de fichiers. C'était ma solution lorsque j'ai eu besoin de télécharger 800 fichiers numérotés consécutivement.