Como posso fazer com que o wget renomeie os arquivos baixados para não incluir a string de consulta?


32

Estou baixando um site com wget e muitos links têm consultas anexadas a eles, então quando faço isso:

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

Acabo com muitos arquivos como este:

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

O que eu gostaria de terminar é:

1.mp3
2.mp3
3.mp3

Tudo isso está ocorrendo no ubuntu linux e eu tenho o wget 1.10.2.

Eu sei que posso fazer isso depois de receber tudo por meio de um script para renomear tudo. No entanto, eu realmente gostaria de uma solução do wget para que eu possa ver os nomes corretos enquanto o download está acontecendo.

Alguém pode me ajudar a desvendar isso?


Poste sua pergunta em www.stackoverflow.com.
Deniz Zoeteman 26/10/2009

3
@TutorialPoint por quê? pergunta está procurando uma maneira de fazê-lo, então o SO apenas migraria de volta para cá.
quack quixote

Bem, não há prazo-wget-way-to-do-it
ayrnieu

1
@ayrnieu: não em um comando, não. e não sem um ajudante. mas você certamente pode fazê-lo com o mínimo de n + 1 wgetcomandos (se não menos).
quack quixote

Respostas:


24

Se o servidor for gentil, ele pode estar colando um cabeçalho de Disposição de Conteúdo no download, informando seu cliente sobre o nome de arquivo correto. Dizer ao wget para ouvir o cabeçalho do nome do arquivo final é tão simples quanto:

wget --content-disposition

Você precisará de uma versão nova do wget para usar esse recurso.

Não tenho idéia de como ele lida com um servidor reivindicando um nome de arquivo '/ etc / passwd'.


Não tenho nenhum problema com esta resposta, pois sem dúvida funciona em algumas situações. Infelizmente, isso não funcionou para mim em relação a algumas páginas servidas na nuvem com ?v=blahversão de tipo. Pode haver alguma maneira específica da cloudfront de solicitar um documento sem eles, não sei, mas não encontrei um, portanto, algo como uma das outras respostas pode ser necessário nesse caso. (Se alguém souber uma maneira de tirar as v=cordas - ou pedir para o Cloudfront não servir - as cordas, eu adoraria ouvir sobre isso.)
lindes

17

Percebi, depois de processar um lote grande, que eu deveria ter instruído wgeta ignorar as cadeias de consulta. Como não queria repetir, criei esse script que funcionou para mim:

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

Coloque isso em um arquivo como rmqstre chmod +x rmqstr sintaxe:./rmqstr <directory (defaults to .)>

Ele removerá as seqüências de consulta de todos os nomes de arquivos recursivamente.


2
Eu adicionaria `-name" \? "` Para encontrar uma parte para limitar apenas aos arquivos necessários :)
Arkadiusz 'voa' Rzadkowolski

4

Eu acho que, para conseguir wgetsalvar como um nome de arquivo diferente do que o URL especifica, você precisa usar o -O filenameargumento Isso só faz o que você deseja quando você fornece um único URL - com vários URLs, todo o conteúdo baixado termina filename.

Mas essa é realmente a resposta. Em vez de tentar fazer tudo em um wgetcomando, use vários comandos. Agora seu fluxo de trabalho se torna:

  1. Execute wgetpara obter o (s) arquivo (s) HTML básico que contém seus links;
  2. Analisar URLs;
  3. Foreach URL terminado em mp3,
    1. URL do processo para obter um nome de arquivo (por exemplo, transformar-se http://foo/bar/baz.mp3?gargle=blasterembaz.mp3
    2. (opcional) verifique se o nome do arquivo não existe
    3. corre wget <URL> -O <filename>

Isso resolve o seu problema, mas agora você precisa descobrir como pegar os arquivos base para encontrar seus mp3URLs.

Você tem um URL de site / base específico em mente? Os passos 1 e 3 serão mais fáceis de lidar com um exemplo concreto.


1

para que eu possa ver os nomes corretos enquanto o download está acontecendo.

ESTÁ BEM. Use wget como você faz normalmente; use o script pós-wget que você normalmente usa, mas processe a saída do wget para que fique mais fácil:

#! /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

Isso ainda mostrará o ?foo=bardownload, mas exibirá o restante do nome em ciano claro.


Isso resolve um pouco o problema dos nomes de arquivos que estão sendo exibidos, mas o OP também deseja que o nome do arquivo final não tenha a string de consulta.
Michael Mior 16/08

1

Eu tenho uma abordagem semelhante à @Gregory Wolf, porque seu código sempre criava mensagens de erro como esta:

mv: './file' e './file' são o mesmo arquivo

Portanto, primeiro verifico se existe uma string de consulta no nome do arquivo antes de mover o arquivo:

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

Isso verificará recursivamente todos os arquivos e removerá todas as cadeias de consulta em seus nomes de arquivos, se disponíveis.


0

Observe esses dois comandos que criei para clonar um site e, após a conclusão do clone, você poderá executar o segundo comando.

O segundo comando examinará todo o clone, procurará por nomes de padrão de arquivo " ? " E removerá a string de consulta do nome do arquivo.

# 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

(Veja no GitHub Gist .)


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.