Как сделать так, чтобы wget переименовал загруженные файлы, чтобы не включать строку запроса?

32

Я загружаю сайт с помощью wget, и ко многим ссылкам прикреплены запросы, поэтому, когда я делаю это:

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

Я получаю много таких файлов:

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

Что я хотел бы закончить это:

1.mp3
2.mp3
3.mp3

Все это происходит в Ubuntu Linux, и у меня есть wget 1.10.2.

Я знаю, что могу сделать это после того, как получу все через скрипт, чтобы переименовать все. Однако мне бы очень хотелось найти решение изнутри wget, чтобы я мог видеть правильные имена во время загрузки.

Может ли кто-нибудь помочь мне разгадать это?

Кит Туомбли
источник
Отправьте свой вопрос на www.stackoverflow.com.
Дениз Зоетман
3
@TutorialPoint почему? Вопрос в том, чтобы найти способ сделать это, поэтому SO просто перенесет его сюда.
шарлатанство
Ну, нет никакого способа сделать это
ayrnieu
1
@ayrnieu: не в одной команде, нет. и не без помощника. но вы, безусловно, можете сделать это всего за n + 1 wgetкоманд (если не меньше).
Квик-кихот

Ответы:

24

Если сервер добрый, он может прикрепить заголовок Content-Disposition к загрузке, сообщая вашему клиенту правильное имя файла. Чтобы заставить wget прослушать этот заголовок для окончательного имени файла, достаточно просто:

wget --content-disposition

Вам понадобится новая версия Wget, чтобы использовать эту функцию.

Я понятия не имею, насколько хорошо он обрабатывает сервер, требующий имя файла '/ etc / passwd'.

Filox
источник
У меня нет проблем с этим ответом, поскольку он, без сомнения, работает в некоторых ситуациях. К сожалению, это не сработало для меня в отношении некоторых страниц с облачным фронтом и ?v=blahверсионированием типов в них. Может быть, есть какой-то специфический для облачного фронта способ запроса документа без них, я не знаю, но мне не удалось найти его, поэтому в таком случае вполне может понадобиться что-то похожее на один из других ответов. (Если кто-нибудь знает способ раздеть - или заставить Cloudfront не обслуживать - v=струны, я хотел бы услышать об этом.)
Линдес
17

После обработки большого пакета я понял, что должен был wgetигнорировать строки запроса. Я не хотел делать это снова, поэтому я сделал этот скрипт, который работал для меня:

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

Поместите это в файл вроде rmqstrи chmod +x rmqstr Синтаксис:./rmqstr <directory (defaults to .)>

Он будет рекурсивно удалять строки запроса из всех имен файлов.

Грегори Вольф
источник
2
Я бы добавил `-name" \? "`, Чтобы найти часть, ограничивающую только необходимые файлы :)
Arkadiusz 'flys' Rzadkowolski
4

Я думаю, wgetчтобы сохранить как имя файла, отличное от указанного в URL, вам нужно использовать -O filenameаргумент. Это только то, что вы хотите, когда вы даете ему один URL - с несколькими URL, весь загруженный контент заканчивается в filename.

Но это действительно ответ. Вместо того, чтобы пытаться сделать все это одной wgetкомандой, используйте несколько команд. Теперь ваш рабочий процесс становится:

  1. Запустите, wgetчтобы получить базовый HTML-файл (ы), содержащий ваши ссылки;
  2. Парсинг по URL;
  3. URL-адрес Foreach, заканчивающийся на mp3,
    1. URL процесса, чтобы получить имя файла (например, превратить http://foo/bar/baz.mp3?gargle=blasterвbaz.mp3
    2. (необязательно) проверьте, что имя файла не существует
    3. бег wget <URL> -O <filename>

Это решает вашу проблему, но теперь вам нужно выяснить, как получить базовые файлы, чтобы найти ваши mp3URL.

Вы имеете в виду конкретный сайт / базовый URL? С шагами 1 и 3 будет легче справиться с конкретным примером.

шарлатан
источник
1

так что я могу видеть правильные имена во время загрузки.

ХОРОШО. Используйте wget как обычно; используйте скрипт post-wget, который вы обычно используете, но обработайте вывод wget так, чтобы это было проще для глаз:

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

Это все равно покажет, ?foo=barкак вы загружаете, но отобразит остальную часть имени в ярком голубом.

ayrnieu
источник
Это несколько решает проблему отображаемых имен файлов, но OP также хочет, чтобы в окончательном имени файла не было строки запроса.
Майкл Миор
1

У меня такой же подход, как у @Gregory Wolf, потому что его код всегда создавал сообщения об ошибках вроде этого

mv: «./file» и «./file» - это один и тот же файл

Таким образом, я сначала проверяю, есть ли строка запроса в имени файла перед перемещением файла:

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

Это будет рекурсивно проверять каждый файл и удалять все строки запроса в их именах файлов, если таковые имеются.

KittMedia
источник
0

Посмотрите на эти две команды, которые я создал для клонирования сайта, и после завершения клонирования вы можете выполнить вторую команду.

Вторая команда просматривает весь клон, ищет имена шаблонов файлов « ? » И удаляет строку запроса из имени файла.

# 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

(Смотрите это в GitHub Gist .)

Виджай Падхария
источник
-2

Еще проще: /unix/196253/how-do-you-rename-files-specifically-in-a-list-that-wget-will-use

Это предполагает метод, который по существу использует функцию переименования wget (может быть изменена для включения каталога) для нескольких файлов. Смотрите вторую версию, предложенную.

robcore
источник
2
Не могли бы вы процитировать соответствующую информацию по ссылке, чтобы мы знали, какой материал, по вашему мнению, отвечает на этот вопрос.
Ramhound