Jak mogę zmienić nazwę pobranych plików przez wget, aby nie zawierały ciągu zapytania?


32

Pobieram witrynę z wget i do wielu linków dołączone są zapytania, więc kiedy to zrobię:

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

Skończyło się z wieloma takimi plikami:

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

Chciałbym skończyć z:

1.mp3
2.mp3
3.mp3

To wszystko dzieje się w Ubuntu Linux i mam wget 1.10.2.

Wiem, że mogę to zrobić po otrzymaniu wszystkiego za pomocą skryptu, aby zmienić nazwę wszystkiego. Jednak naprawdę chciałbym rozwiązania z poziomu wget, aby zobaczyć prawidłowe nazwy w trakcie pobierania.

Czy ktoś może mi pomóc to rozwiązać?


Opublikuj swoje pytanie na stronie www.stackoverflow.com.
Deniz Zoeteman

3
@TutorialPoint dlaczego? pytanie dotyczy sposobu, w jaki można to zrobić, SO po prostu migrowałoby to z powrotem tutaj.
quack quixote

Cóż, nie ma żadnej drogi do zrobienia
ayrnieu

1
@ayrnieu: nie w jednym poleceniu, nie. i nie bez pomocnika. ale z pewnością możesz to zrobić za pomocą zaledwie n + 1 wgetpoleceń (jeśli nie mniej).
szarlatan

Odpowiedzi:


24

Jeśli serwer jest miły, może przyklejać do pobierania nagłówek Content-Disposition, informując klienta o poprawnej nazwie pliku. Powiedzenie wget, aby odsłuchało ten nagłówek dla końcowej nazwy pliku, jest tak proste, jak:

wget --content-disposition

Aby korzystać z tej funkcji, potrzebujesz nowej wersji wget.

Nie mam pojęcia, jak dobrze radzi sobie z serwerem żądającym nazwy pliku „/ etc / passwd”.


Nie mam problemu z tą odpowiedzią, ponieważ bez wątpienia działa ona w niektórych sytuacjach. Niestety nie działało to w przypadku niektórych stron przechowywanych w chmurze z ?v=blahwersjonowaniem typów. Nie może istnieć jakiś specyficzny dla chmury sposób na zażądanie dokumentu bez nich, nie wiem, ale nie udało mi się go znaleźć, więc w takim przypadku może być potrzebna coś takiego jak jedna z pozostałych odpowiedzi. (Jeśli ktoś zna sposób na rozebranie - lub nakłonienie Cloudfront, aby nie służył - v=struny, chciałbym o tym usłyszeć.)
Lindes

17

Po przetworzeniu dużej partii zrozumiałem, że powinienem był wgetzignorować ciągi zapytania. Nie chciałem tego robić od nowa, dlatego stworzyłem ten skrypt, który działał dla mnie:

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

Umieść to w pliku podobnym do rmqstri chmod +x rmqstr Składnia:./rmqstr <directory (defaults to .)>

Spowoduje to rekurencyjne usunięcie ciągów zapytań ze wszystkich nazw plików.


2
Dodałbym `-name ' \? ' ', Aby znaleźć część ograniczającą tylko do potrzebnych plików :)
Arkadiusz' lata 'Rzadkowolski

4

Myślę, że wgetaby zapisać jako nazwę pliku inną niż adres URL, musisz użyć -O filenameargumentu. To robi tylko to, co chcesz, jeśli nadasz mu pojedynczy adres URL - w przypadku wielu adresów URL cała pobrana zawartość kończy się w filename.

Ale to naprawdę odpowiedź. Zamiast próbować zrobić to wszystko w jednym wgetpoleceniu, użyj wielu poleceń. Teraz Twój przepływ pracy staje się:

  1. Uruchom, wgetaby uzyskać podstawowe pliki HTML zawierające linki;
  2. Analiza adresów URL;
  3. Każdy adres URL kończący się na mp3,
    1. przetworzyć adres URL, aby uzyskać nazwę pliku (np. zmienić http://foo/bar/baz.mp3?gargle=blasternabaz.mp3
    2. (opcjonalnie) sprawdź, czy nazwa pliku nie istnieje
    3. biegać wget <URL> -O <filename>

To rozwiązuje problem, ale teraz musisz dowiedzieć się, jak pobrać pliki podstawowe, aby znaleźć mp3adresy URL.

Czy masz na myśli konkretny adres witryny / podstawowy? Kroki 1 i 3 będą łatwiejsze do wykonania na konkretnym przykładzie.


1

więc widzę prawidłowe nazwy w trakcie pobierania.

DOBRZE. Używaj wget tak jak zwykle; użyj skryptu post-wget, którego zwykle używasz, ale przetwarzaj dane wyjściowe wget, aby było łatwiejsze dla oczu:

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

Będzie to nadal wyświetlać podczas ?foo=barpobierania, ale wyświetli resztę nazwy w jasnobłękitnym kolorze.


To nieco rozwiązuje problem wyświetlania nazw plików, ale OP chce również, aby końcowa nazwa pliku nie zawierała ciągu zapytania.
Michael Mior

1

Mam podobne podejście jak @Gregory Wolf, ponieważ jego kod zawsze tworzył komunikaty o błędach:

mv: „./file” i „./file” są tym samym plikiem

Dlatego najpierw sprawdzam, czy w nazwie pliku znajduje się ciąg zapytania, przed przeniesieniem pliku:

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

Spowoduje to rekursywne sprawdzenie każdego pliku i usunięcie wszystkich ciągów zapytań w nazwach plików, jeśli są one dostępne.


0

Spójrz na te dwa polecenia, które utworzyłem, aby sklonować witrynę, a po zakończeniu klonowania możesz wykonać drugie polecenie.

Drugie polecenie sprawdzi cały klon, wyszuka nazwy wzorców plików „ ? ” I usunie ciąg zapytania z nazwy pliku.

# 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

(Zobacz w GitHub Gist .)


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.