Czy mogę przestać tworzyć duplikaty?

13

Jeśli uruchomię wget dwa razy, nie rozpozna, że ​​już pobrał ten plik i utworzy nowy. Czy jest jakiś sposób, aby zapobiec ponownemu pobieraniu pliku?

$ wget https://cdn.sstatic.net/askubuntu/img/logo.png
...
Saving to: ‘logo.png’
...

$ wget https://cdn.sstatic.net/askubuntu/img/logo.png
...
Saving to: ‘logo.png.1’
...

(Chętnie używam curl lub podobnej skryptowalnej alternatywy, jeśli wget nie może tego zrobić.)

david.libremone
źródło
9
Tworzy nowy, ponieważ rozpoznaje, że plik tam jest!
nico

Odpowiedzi:

17

Sugeruję skorzystanie z tej -Nopcji.

-N
--timestamping
    Turn on time-stamping.

Umożliwia znacznik czasu, który ponownie pobiera plik tylko wtedy, gdy jest nowszy na serwerze niż wersja pobrana.

$ wget -N https://cdn.sstatic.net/askubuntu/img/logo.png
...
Saving to: ‘logo.png’
...

$ wget -N https://cdn.sstatic.net/askubuntu/img/logo.png
...
Server file no newer than local file ‘logo.png’ -- not retrieving.

Zastrzeżenie (od komentarza KasiyA)

Jeśli serwer nie jest poprawnie skonfigurowany, zawsze może zgłosić, że plik jest nowy i -Nzawsze pobierze go ponownie. W takim przypadku -ncjest to prawdopodobnie lepsza opcja.

Jofel
źródło
3
Gdy serwer nie jest odpowiednio skonfigurowany, -Nmoże się nie powieść, a wget zawsze pobierze ponownie. Czasami więc -ncjest lepiej niż-N
αғsнιη
1
@Kasiy dzięki za komentarz, wydaje się, że nie ma dobrej opcji dla wszystkich przypadków.
jofel
16

Tak, to jest -copcja.

--continue
    Continue getting a partially-downloaded file.  This is useful when you want to
    finish up a download started by a previous instance of Wget, or by another
    program.

Jeśli plik jest taki sam, druga próba pobierania zostanie zatrzymana.

$ wget -c https://cdn.sstatic.net/askubuntu/img/logo.png
...
Saving to: ‘logo.png’
...

$ wget -c https://cdn.sstatic.net/askubuntu/img/logo.png
...
The file is already fully retrieved; nothing to do.

Ostrzeżenia (od komentarzy Jofela)

Jeśli plik zmienił się na serwerze, -copcja może dawać nieprawidłowe wyniki.

Z -c, wget po prostu prosi serwer o wszelkie dane poza częścią już pobranego pliku, nic więcej. Nie sprawdza, czy nastąpiła zmiana w części pliku, który jest już pobrany. W ten sposób możesz uszkodzić plik, który jest mieszanką starego i nowego pliku.


Test lokalny

Można go przetestować uruchamiając prosty lokalnego serwera WWW w następujący sposób (dzięki @roadmr „s odpowiedź ):

Otwórz okna terminala i wpisz:

cd /path/to/parent-download-dir/
python -m SimpleHTTPServer

Teraz otwórz kolejny terminal i wykonaj:

wget -c http://localhost:8000/filename-to-download

Pamiętaj, że filename-to-downloadjest to plik, w /path/to/parent-download-dir/którym się znajduje, w którym chcemy go pobrać.

Teraz, jeśli uruchomisz polecenie wget wiele razy, zobaczysz:

The file is already fully retrieved; nothing to do.

Ok, teraz przejdź do /path/to/parent-download-dir/katalogu i dodaj coś do pliku źródłowego, na przykład jeśli jest to plik tekstowy, dodaj do niego prostą dodatkową linię i zapisz plik. Teraz spróbuj z wget -c .... Świetnie, teraz zobaczysz, że plik ponownie się pobiera, ale już go wcześniej pobrałeś.

Powód: dlaczego ponowne pobieranie?

ponieważ jego rozmiar zmienił się na większy niż stary pobrany plik i nic więcej.

αғsнιη
źródło
1
To nie działa poprawnie, jeśli plik został zmieniony na serwerze między pobranymi plikami. W najgorszym przypadku (rozmiar pliku wzrósł) otrzymujesz uszkodzony plik.
jofel
1
@ jofel tak -ncnie jest tak , jak powiedziałeś, ale -copcja będzie działać i dlatego wspomniałem o -copcji najpierw.
αғsнιη
Dzięki -c, wgetprosi serwer o jakichkolwiek danych poza częścią już pobranego pliku, nic innego. Nie sprawdza, czy w międzyczasie nastąpiła zmiana w już pobranej części pliku na serwerze. W najgorszym przypadku otrzymujesz uszkodzony plik będący mieszanką starego i nowego pliku.
jofel
po zapoznaniu się z opcji myślę, że to ma sens tylko na coś takiego pliku logu (gwarantowanej przyrostowych aktualizacji) we wszystkich innych przypadkach myślę -N lub -nc są bardziej odpowiednie, jak radzą sobie z całych plików
david.libremone
3

Istnieje również inna opcja wywołania -ncwgetting:

--no-clobber
   If a file is downloaded more than once in the same directory, Wget's behavior
   depends on a few options, including -nc.  In certain cases, the local file will
   be clobbered, or overwritten, upon repeated download.  In other cases it will be
   preserved.

Po -ncokreśleniu opcji Wget odmówi pobrania kopii tego samego pliku. Jeśli masz ten sam plik, który wgetpróbuje pobrać, odmówi on pobrania, chyba że zmienisz nazwę pliku lokalnego lub usuniesz go.

$ wget -nc https://cdn.sstatic.net/askubuntu/img/logo.png
...
Saving to: ‘logo.png’
...

$ wget -nc https://cdn.sstatic.net/askubuntu/img/logo.png
File ‘logo.png’ already there; not retrieving.

Czasami ta opcja jest bardzo dobra i zaleciłem użycie -ncopcji zamiast obu -club -Nopcji, ponieważ te opcje zastąpią plik do pobrania plikiem lokalnym, jeśli mają te same nazwy.

Zastrzeżenie (od komentarza Jofela)

-ncOpcja nie aktualizuje plik jeśli został zmieniony na serwerze. Jeśli wiesz, że plik ulegnie zmianie, -Nopcja jest lepsza. Jeśli wiesz, że plik się nie zmieni (lub nie obchodzi cię to), -ncjest w porządku.

αғsнιη
źródło
1

Wiem, że było to konkretne pytanie dotyczące wget, ale OP wspomniało: „Cieszę się, że używam curl lub podobnej skryptowalnej alternatywy, jeśli wget nie może tego zrobić”. Nie jestem pewien, jakie jest to wymaganie (wiele plików, zachowaj starą wersję, jeśli jest inna niż oryginalna, zastąp nową pobraną wersją). W zależności od tego, czego chcesz i od tego, jak chcesz obsługiwać duplikaty, możesz potrzebować więcej niż to. Bardzo prostym sposobem na zrobienie tego, co chcesz, jest po prostu użycie curl.

curl http://cdn.sstatic.net/askubuntu/img/logo.png?v=ca4d192163aa > logo.png

To polecenie zamienia za każdym razem stary plik na nowo pobrany.

Nie wysyłaj tego do terminala (bez „> [nazwa pliku]”), jeśli pobierasz plik binarny zamiast tekstu. Może to potencjalnie zepsuć sesję terminala. Jeśli zrobisz to przypadkowo, może być konieczne otwarcie kolejnej sesji powłoki / terminalu.

Władca Goblinów
źródło
Jeśli twój terminal jest w złym stanie, ponieważ wyświetlałeś pliki binarne, być może łatwiej jest wywołać program „reset” niż otwarcie nowego terminala.
jofel
masz rację, że nie miałem jasności co do moich wymagań, szczęśliwy wynik to, że dowiedziałem się o kilku innych opcjach :) dzięki
david.libremone
Dzięki @jofel ^^ nie wiedziałem o „resecie” Zawsze po prostu zamknąłem otworzyłem nową kartę i zamknąłem zniekształconą kartę, kiedy to się zdarzyło ... chociaż tak naprawdę nie zdarzało się tak często.
Goblinlord,