¿Cómo puedo hacer que wget cambie el nombre de los archivos descargados para que no incluyan la cadena de consulta?

32

Estoy descargando un sitio con wget y muchos de los enlaces tienen consultas adjuntas, así que cuando hago esto:

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

Termino con muchos archivos como este:

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

Lo que me gustaría terminar es:

1.mp3
2.mp3
3.mp3

Todo esto ocurre en ubuntu linux y tengo wget 1.10.2.

Sé que puedo hacer esto después de obtener todo mediante un script para cambiar el nombre de todo. Sin embargo, realmente me gustaría una solución desde wget para poder ver los nombres correctos mientras se realiza la descarga.

¿Alguien puede ayudarme a desentrañar esto?

Keith Twombley
fuente
Publique su pregunta en www.stackoverflow.com.
Deniz Zoeteman
3
@TutorialPoint ¿por qué? la pregunta está buscando una manera de hacerlo dentro de wget, SO simplemente lo migrará aquí.
quack quijote
Bueno, no hay una manera de hacerlo
ayrnieu
1
@ayrnieu: no en un comando, no. y no sin ayudante. pero ciertamente puede hacerlo con tan solo n + 1 wgetcomandos (si no menos).
quack quijote

Respuestas:

24

Si el servidor es amable, podría estar pegando un encabezado de Disposición de contenido en la descarga que informa a su cliente del nombre de archivo correcto. Decirle a wget que escuche ese encabezado para el nombre de archivo final es tan simple como:

wget --content-disposition

Necesitará una versión más reciente de wget para usar esta función.

No tengo idea de qué tan bien maneja un servidor que reclama un nombre de archivo de '/ etc / passwd'.

Filox
fuente
No tengo ningún problema con esta respuesta, ya que sin duda funciona para algunas situaciones. Desafortunadamente, no funcionó para mí con respecto a algunas páginas atendidas en la nube con ?v=blahversiones de tipo en ellas. Puede haber alguna forma específica de frente de la nube para solicitar un documento sin estos, no lo sé, pero no pude encontrar uno, por lo que puede ser necesario algo así como una de las otras respuestas en tal caso. (Si alguien sabe de una manera de despojar, o hacer que Cloudfront no sirva, las v=cadenas, me encantaría
saberlo
17

Después de procesar un lote grande, me di cuenta de que debería haberle dado instrucciones wgetpara ignorar las cadenas de consulta. No quería volver a hacerlo, así que hice este script que funcionó para mí:

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

Pon eso en un archivo como rmqstry chmod +x rmqstr Sintaxis:./rmqstr <directory (defaults to .)>

Eliminará las cadenas de consulta de todos los nombres de archivo de forma recursiva.

Gregory Wolf
fuente
2
Yo agregaría `-name" \? "` Para encontrar una parte que se limite solo a los archivos necesarios :)
Arkadiusz 'vuela' Rzadkowolski el
4

Creo que, para poder wgetguardar como un nombre de archivo diferente al que especifica la URL, debe usar el -O filenameargumento. Eso solo hace lo que quieres cuando le das una sola URL: con varias URL, todo el contenido descargado termina en filename.

Pero esa es realmente la respuesta. En lugar de intentar hacerlo todo en un solo wgetcomando, use varios comandos. Ahora su flujo de trabajo se convierte en:

  1. Ejecute wgetpara obtener los archivos HTML base que contienen sus enlaces;
  2. Analizar URLs;
  3. Foreach URL que termina en mp3,
    1. procesar URL para obtener un nombre de archivo (por ejemplo, convertirlo http://foo/bar/baz.mp3?gargle=blasterenbaz.mp3
    2. (opcional) verifique que el nombre de archivo no exista
    3. correr wget <URL> -O <filename>

Eso resuelve su problema, pero ahora necesita descubrir cómo tomar los archivos base para encontrar sus mp3URL.

¿Tiene en mente un sitio particular / URL base? Los pasos 1 y 3 serán más fáciles de manejar con un ejemplo concreto.

quijote curandero
fuente
1

así puedo ver los nombres correctos mientras se realiza la descarga.

OKAY. Use wget como lo hace normalmente; use el script post-wget que usa normalmente, pero procese la salida de wget para que sea más fácil a la vista:

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

Esto seguirá mostrándolo ?foo=barmientras lo descarga, pero mostrará el resto del nombre en cian brillante.

ayrnieu
fuente
Esto resuelve un poco el problema de los nombres de archivo que se muestran, pero el OP también quiere que el nombre del archivo final no tenga la cadena de consulta.
Michael Mior
1

Tengo un enfoque similar a @Gregory Wolf porque su código siempre creaba mensajes de error como este:

mv: './file' y './file' son el mismo archivo

Por lo tanto, primero verifico si hay una cadena de consulta en el nombre de archivo antes de mover el archivo:

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

Esto verificará recursivamente cada archivo y eliminará todas las cadenas de consulta en sus nombres de archivo, si están disponibles.

KittMedia
fuente
0

Mire estos dos comandos que creé para clonar un sitio, y después de hacer el clon, puede ejecutar el segundo comando.

El segundo comando examinará todo el clon, buscará los nombres de patrón de archivo " ? " Y eliminará la cadena de consulta del nombre del archivo.

# 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

( Véalo en GitHub Gist .)

Vijay Padhariya
fuente
-2

Aún más fácil es esto: /unix/196253/how-do-you-rename-files-specífico-in-a-list-that-wget-will-use

Esto sugiere un método que esencialmente utiliza la función de cambio de nombre de wget (puede modificarse para incluir el directorio) para múltiples archivos. Ver la segunda versión propuesta.

robcore
fuente
2
¿Puede citar la información relevante del enlace para que sepamos qué material cree que responde esta pregunta?
Ramhound