Comment puis-je faire en sorte que wget renomme les fichiers téléchargés pour ne pas inclure la chaîne de requête?


32

Je télécharge un site avec wget et de nombreux liens sont associés à des requêtes, alors quand je fais cela:

wget -nv -c -r -H -A mp3 -nd http://url.to.old.podcasts.com/

Je me retrouve avec beaucoup de fichiers comme celui-ci:

1.mp3?foo=bar
2.mp3?blatz=pow
3.mp3?fizz=buzz

Je voudrais finir avec:

1.mp3
2.mp3
3.mp3

Tout cela se déroule sous Ubuntu Linux et j'ai wget 1.10.2.

Je sais que je peux le faire après avoir tout obtenu via un script pour tout renommer. Cependant, j'aimerais vraiment une solution dans wget afin que je puisse voir les noms corrects au fur et à mesure du téléchargement.

Quelqu'un peut-il m'aider à résoudre ce problème?


Postez votre question sur www.stackoverflow.com.
Deniz Zoeteman

3
@TutorialPoint pourquoi? question est à la recherche d'un moyen de le faire à l'intérieur de wget, SO le migrerait simplement ici.
Quack Quichote

Eh bien, il n'y a pas de façon de le faire à l'intérieur de wget
ayrnieu

1
@ayrnieu: pas dans une seule commande, non. et non sans aide. mais vous pouvez certainement le faire avec aussi peu que n + 1 wgetcommandes (sinon moins).
Quack Quichote

Réponses:


24

Si le serveur est gentil, il peut coller un en-tête Content-Disposition sur le téléchargement pour informer votre client du nom de fichier correct. Dire à wget d'écouter cet en-tête pour le nom de fichier final est aussi simple que:

wget --content-disposition

Vous aurez besoin d'une nouvelle version de wget pour utiliser cette fonctionnalité.

Je n'ai aucune idée de la façon dont il gère un serveur revendiquant un nom de fichier «/ etc / passwd».


Je n'ai aucun problème avec cette réponse, car cela fonctionne sans aucun doute pour certaines situations. Malheureusement, cela n'a pas fonctionné pour moi en ce qui concerne certaines pages hébergées dans le cloud avec le ?v=blahtype de version. Il peut y avoir un moyen spécifique à cloudfront de demander un document sans ceux-ci, je ne sais pas, mais je n'ai pas réussi à en trouver un, donc quelque chose comme l'une des autres réponses pourrait bien être nécessaire dans un tel cas. (Si quelqu'un connaît un moyen de dépouiller - ou de faire en sorte que Cloudfront ne serve pas - les v=cordes, j'aimerais en entendre parler.)
lindes

17

J'ai réalisé après avoir traité un gros lot que j'aurais dû demander wgetd'ignorer les chaînes de requête. Je ne voulais pas recommencer alors j'ai fait ce script qui a fonctionné pour moi:

# /bin/bash
for i in `find $1 -type f`
do
    mv $i `echo $i | cut -d? -f1`
done

Mettez cela dans un fichier comme rmqstret chmod +x rmqstr Syntaxe:./rmqstr <directory (defaults to .)>

Il supprimera les chaînes de requête de tous les noms de fichiers de manière récursive.


2
J'ajouterais `-name" \? "` Pour trouver une partie à limiter uniquement aux fichiers nécessaires :)
Arkadiusz 'vole' Rzadkowolski

4

Je pense que, pour pouvoir wgetenregistrer sous un nom de fichier différent de celui spécifié par l'URL, vous devez utiliser l' -O filenameargument. Cela ne fait que ce que vous voulez lorsque vous lui donnez une seule URL - avec plusieurs URL, tout le contenu téléchargé se retrouve filename.

Mais c'est vraiment la réponse. Au lieu d'essayer de tout faire en une seule wgetcommande, utilisez plusieurs commandes. Maintenant, votre flux de travail devient:

  1. Exécutez wgetpour obtenir le ou les fichiers HTML de base contenant vos liens;
  2. Analyser les URL;
  3. URL foreach se terminant par mp3,
    1. traiter l'URL pour obtenir un nom de fichier (par exemple, transformer http://foo/bar/baz.mp3?gargle=blasterenbaz.mp3
    2. (facultatif) vérifiez que le nom de fichier n'existe pas
    3. courir wget <URL> -O <filename>

Cela résout votre problème, mais vous devez maintenant trouver comment récupérer les fichiers de base pour trouver vos mp3URL.

Avez-vous en tête une URL de site / base particulière? Les étapes 1 et 3 seront plus faciles à gérer avec un exemple concret.


1

afin que je puisse voir les noms corrects pendant le téléchargement.

D'ACCORD. Utilisez wget comme vous le faites normalement; utilisez le script post-wget que vous utilisez normalement, mais traitez la sortie de wget de manière à ce qu'elle soit plus agréable à l'oeil:

#! /bin/sh
exec wget --progress=bar:force $* 2>&1 | \
  perl -pe 'BEGIN { $| = 1 } s,(?<=`)([^\x27?]+),\e[36;1m$1\e[0m, if /^Saving/'
cgi-cut # rename files

Cela affichera toujours le ?foo=barpendant le téléchargement, mais affichera le reste du nom en cyan brillant.


Cela résout quelque peu le problème d'affichage des noms de fichiers, mais l'OP souhaite également que le nom de fichier final ne contienne pas la chaîne de requête.
Michael Mior

1

J'ai une approche similaire à @Gregory Wolf car son code a toujours créé des messages d'erreur comme celui-ci:

mv: './file' et './file' sont le même fichier

Ainsi, je vérifie d'abord s'il y a une chaîne de requête dans le nom de fichier avant de déplacer le fichier:

for f in $(find $1 -type f); do
    if [ $f = ${f%%\?*} ]; then continue; fi
    mv "${f}" "${f%%\?*}"
done

Cela vérifiera récursivement chaque fichier et supprimera toutes les chaînes de requête dans leurs noms de fichiers si disponibles.


0

Regardez ces deux commandes que j'ai créées pour cloner un site, et une fois le clonage terminé, vous pouvez exécuter la deuxième commande.

La deuxième commande examinera l'intégralité du clone, recherchera les noms de modèle de fichier " ? " Et supprimera la chaîne de requête du nom de fichier.

# Clone entire site.
    wget --content-disposition --execute robots=off --recursive --no-parent --continue --no-clobber http://example.com

# Remove query string from a static resource.
for i in `find $1 -type f -name "*\?*"`; do mv $i `echo $i | cut -d? -f1`; done

(Voir dans GitHub Gist .)


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.