Wget - wenn / sonst Download-Bedingung?

3219
Kai

Ich möchte, dass wget einen bestimmten Dateityp einem anderen vorgezogen, wenn die Dateien denselben Basisnamen haben.

Zum Beispiel:

Wenn foo.ogg verfügbar ist, laden Sie foo.mp3 nicht herunter


die Art und Weise, wie ich wget bisher zum Crawlen / automatischen Herunterladen verwende (wenn jemand interessiert ist):

wget -Dfoo.com -I /folder/ -r -l 1 -nc -A.ogg,.mp3 http://www.foo.com/folder/ 

aber das bringt mir natürlich .mp3 UND .ogg- Dateien. Irgendwelche Ideen?

  • (Syntax-Erläuterung:
    -D: Nur von dieser Domäne
    herunterladen -I: Nur von diesem Unterordner der Domäne herunterladen
    -r: rekursiv (Links und Verzeichnisstruktur folgen)
    -l 1: Nur 1 Link folgen
    -nc: no clobber = download Nur wenn die Datei nicht existiert
    -A: Akzeptiere / Download nur alle * .ogg und * .mp3 (verwerfe notwendige HTML-Dateien)
    (-i (optional vor der URL)): Liest URLs von der URL, lädt aber auch andere Dateitypen wie .png, die Sie eigentlich gar nicht wollten / verwerfen
3

2 Antworten auf die Frage

6
Eroen

Single files

To accomplish "If file x exists, download it; otherwise download file y", you can do the following:

wget x || wget y 

If x exists, it is downloaded and wget returns true, thus the second part is skipped. If x does not exist, wget returns some error code (probably 8) and the second part of the expression is evaluated (which downloads y).

Recursively

That obviously won't help you much for your recursive download, though. I would be surprised if wget has the facilities to accommodate masking with this level of sophistication. The man page doesn't appear to cover any form of fancy conditionals either. A slightly modified approach could work, though.

(It appears to be difficult to convince wget to produce a list of things it wants to download. My first idea was to create this and filter it appropriately before downloading, much like @utkuerd suggests.)

A starting point would naturally be to download all the ogg files first, presumably by

wget -Dfoo.com -I /folder/ -r -l 1 -nc -A.ogg -i http://www.foo.com/folder/ 

The remaining mp3 files could then be downloaded by the same method, provided you have a suitable mask to supply as a --reject list. This list should contain the name of every mp3 file you don't want to download.

Assuming the I suggest you create this list as follows

bl=($(find ./ -name '*.ogg' -exec basename -s .ogg {} \+ | sed 's/\(^.\+$\)/\1.mp3/' ) ) 

You now have a bash array of the mp3 files to block.

To download only the unblocked mp3 files, you could use

IFS=','; wget -Dfoo.com -I /folder/ -r -l 1 -nc -A.mp3 -R"$" -i http://www.foo.com/folder/; unset IFS 

The IFS variable must be modified so the list won't be space separated.

Obviously, this will go badly to varous degrees if the list of ogg files is longer than getconf ARG_MAX (it will break the wget command) or the filenames contain whitespace (it will break the blocklist, potentially giving you and extra file and (unlikely) a missing file). Both are fixable.

Note that superfluous commas in the reject list gives interesting results.

Writeup of @Bob's excellent suggestion

(see comment below)

After getting the ogg files with

wget -Dfoo.com -I /folder/ -r -l 1 -nc -A.ogg -i http://www.foo.com/folder/ 

you could create dummy mp3 files like so

find ./ -name '*.ogg' | sed 's/ogg$/mp3/' | xargs -d '\n' touch 

and get the remaining mp3 files with (exploiting -nc)

wget -Dfoo.com -I /folder/ -r -l 1 -nc -A.mp3 -i http://www.foo.com/folder/ 

The superfluous mp3 files can then be removed with something like

find ./ -name '*.mp3' -size 0 -exec rm '{}' \+ 

I tested that this works with spaces in the names.

Ich denke irgendwie über die "Windows-Batch-Datei" nach, aber wäre es nicht möglich, (anstatt eine Ablehnungsliste anzugeben, und da "-nc" angegeben ist) alle "ogg" -Dateien herunterzuladen, sie alle durchlaufen " Berühren Sie eine `mp3`-Datei mit dem gleichen Namen (0 Byte), laden Sie alle Dateien als` mp3` mit `-nc` herunter, sodass diejenigen, die als` ogg` existieren, und das entsprechende 0-Byte `mp3` übersprungen werden. dann durchlaufen Sie die `ogg`s, um die mp3-Versionen von ihnen zu löschen (oder löschen Sie einfach alle 0-Byte-` mp3`s). Die Ablehnungsliste ist wahrscheinlich besser, obwohl dies ARG_MAX- und Whitespace-Probleme vollständig vermeiden würde. Bob vor 12 Jahren 2
Das Beste, funktioniert wie ein Zauber! Danke euch allen. Nun, ich habe mir gedacht, das Herunterladen mit meinem obigen Befehl kann sehr zeitaufwändig sein, besonders wenn die Dateien in der Verzeichnisstruktur manchmal 1 Link tiefer sind: Zuerst muss ich alles herunterladen / analysieren, um auf die .ogg-Dateien zuzugreifen wieder muss ich das gleiche für die restlichen .mp3-dateien tun, da i -A.ogg die html-dateien verworfen hat, um zu analysieren ... ** Gibt es eine Möglichkeit, die .html-dateien nicht zu verwerfen, um dies tun zu können sie ein zweites Mal offline analysieren? ** Kai vor 12 Jahren 0
Um die HTML-Dateien zu behalten, würde ich jetzt einfach die Option `-A ogg, htm, html` verwenden. Kai vor 11 Jahren 0
2
infiniteRefactor

Ich glaube nicht, dass eine Option von wget in der Lage ist, unter gegebenen Dateinamensmustern auf intelligente Weise zu wählen. Wahrscheinlich benötigen Sie ein Skript, um das zu erreichen, was Sie möchten. Sie sollten die Verzeichnisliste abrufen, selbst analysieren und dann die gewünschten Dateien herunterladen.

Für heruntergeladene und verworfene PNG-Dateien wurde die Markierung -i falsch verwendet. -i Flag gibt eine Datei (oder URL) an, die die herunterzuladenden URLs enthält. Sie sollten den Startpunkt ohne Flagge angeben. Wenn Sie das Flag -i entfernen, werden keine anderen Dateitypen heruntergeladen, sondern nur .ogg, .mp3 und die erforderlichen HTML-Dateien. HTML-Dateien werden danach gelöscht.

Als Alternative kann ich alle URLs aus einem gespeicherten HTML-Index mit "awk" BEGIN " nr="">2 "index.html >> url-list.txt" Verwerfen unnötiger Zeilen per Hand und Herunterladen über: `wget -v -nc -A ogg -i url-list.txt` ** Wie kann ich nur bestimmte URLs auslesen? **, wie www.foo.com/(randomfolder)/(randomfilename).mp3 Kai vor 12 Jahren 0
** Über -I: ** Ich habe versucht, -I / folder wegzulassen und / oder -D in -Dwww.foo.com/folder zu ändern. Dies hatte jedoch keine Auswirkungen auf die noch heruntergeladenen .png-Dateien. wget manual sagt: Die Option _-I akzeptiert eine durch Kommas getrennte Liste der Verzeichnisse, die im Abruf enthalten sind. Alle anderen Verzeichnisse werden einfach ignoriert. Die Verzeichnisse sind absolute Pfade. "Wenn Sie also von http: // host / people / bozo / 'herunterladen möchten, folgen Sie nur Links zu bozos Kollegen im` / people'-Verzeichnis und den gefälschten Skripten in / cgi-bin'. Sie können angeben: _ (...) Kai vor 12 Jahren 0
(...) _der gefälschten Skripte in `/ cgi-bin 'können Sie angeben: wget -I / people, / cgi-bin http: // host / people / bozo / _" ---- (anscheinend auch sagt, -D macht nur Sinn, wenn es mit -H verwendet wird (wget "spanning" erlaubt, Links / Downloads zu anderen Domains zu folgen) - es erstellt jedoch Verzeichnisse für andere Domains, die ich jedoch nicht wollte. Kai vor 12 Jahren 0
Es gibt nichts Falsches -Ich. Ich bezog mich auf die Option -i (kleines I), die Sie am Ende vor der URL verwendet haben. Ich denke nicht, dass Sie das brauchen, und wenn Sie es verwenden, werden alle URLs in der Indexdatei (einschließlich Ordnersymbole usw.) vor dem Verwerfen heruntergeladen. infiniteRefactor vor 12 Jahren 1
sehr gut, danke! Entschuldigung, ich habe nicht aufgepasst, du hattest recht. Kai vor 11 Jahren 0