2012-03-26 6 views
58

Ho un elenco di URL in un file chiamato urls.txt. Ogni riga contiene 1 URL. Voglio scaricare tutti i file contemporaneamente usando cURL. Non riesco a trovare il giubbotto unico giusto in basso.Invia l'output di cat a cURL per scaricare un elenco di file

ho provato:

$ cat urls.txt | xargs -0 curl -O 

Ma che mi dà solo l'ultimo file nell'elenco.

+7

'for i in $ (urls.txt cat); arricciare -O $ i; done' – bkconrad

+0

Grazie, @bkconrad. Ho avuto problemi con newlines su Windows, però, l'ho corretto con 'tr':' for i in $ (cat urls.txt); do curl -O $ (echo $ i | tr '\ r' ''); done' – biphobe

risposta

100

Questo funziona per me:

$ xargs -n 1 curl -O < urls.txt 

Sono in FreeBSD. I tuoi xarg potrebbero funzionare diversamente.

Si noti che questo esegue sequenziale curl s, che è possibile visualizzare come inutilmente pesante. Se si desidera risparmiare un po 'di quella in testa, il seguente dovrebbe funzionare in bash:

$ curl $(printf ' -O %s' $(<urls.txt)) 

Oppure, se si utilizza una shell POSIX, piuttosto che bash:

$ curl $(printf ' -O %s' $(cat urls.txt)) 

Questo si basa su printf' Il comportamento di ripetere il modello di formato per esaurire l'elenco degli argomenti dei dati. Il comando curl può accettare più URL e recuperarli tutti, riciclando la connessione esistente (HTTP/1.1), ma è necessario l'opzione -O prima di ciascuno per il download di e il salvataggio di per ciascun obiettivo.

Si noti che questo metodo non-xargs può anche aumentare rispetto ai limiti di sistema per elenchi di URL molto grandi. Ricerca ARG_MAX e MAX_ARG_STRLEN se questo è un problema.

+0

Sembra funzionare, ma mi fornisce solo un file HTML di 125 byte contenente il nome del file, ** non ** il contenuto del file attuale. – Finch

+1

Ah, capisco. C'era un reindirizzamento coinvolto, quindi avevo bisogno di aggiungere l'opzione '-L' a' arricciare '. – Finch

+4

Grazie per il suggerimento! Questo funziona sul mio Mac, ma preferisco la versione della pipeline 'cat urls.txt | xargs -n 1 arricciatura -O' ;-) – orzechow

7

Oppure si può semplicemente fare questo:

cat urls.txt | xargs curl -O 

Hai solo bisogno di utilizzare il parametro -I quando si desidera inserire l'uscita gatto nel bel mezzo di un comando.

+1

non sono sicuro del motivo per cui questo è stato rifiutato ma funziona perfettamente per me, ma invece di un file di testo piatto per l'input ho avuto l'output di grep – rob

+1

Probabilmente downvoted perché è sbagliato. L'opzione '-o' per arricciatura specifica un file di output come argomento. Altre risposte raccomandano '-O', che dice a curl di determinare il nome locale in base al nome remoto del file. – ghoti

6

Ecco come lo faccio su un Mac (OSX), ma dovrebbe funzionare altrettanto bene su altri sistemi:

Quello che vi serve è un file di testo che contiene i link per il ricciolo

in questo modo :

http://www.site1.com/subdirectory/file1-[01-15].jpg 
    http://www.site1.com/subdirectory/file2-[01-15].jpg 
    . 
    . 
    http://www.site1.com/subdirectory/file3287-[01-15].jpg 

In questo caso ipotetico, il file di testo ha 3287 linee e ogni riga è che codifica per 15 immagini.

Diciamo che salviamo questi collegamenti in un file di testo chiamato testcurl.txt al livello superiore (/) del nostro disco rigido.

Ora dobbiamo andare nel terminale e digitare il seguente comando nella shell bash:

for i in "`cat /testcurl.txt`" ; do curl -O "$i" ; done 

Assicurarsi che si sta utilizzando di nuovo zecche (`) Assicurarsi inoltre che la bandiera (-O) è o maiuscola e non uno zero

con la bandiera -O, il nome del file originale verrà presa

Buon download!

+0

È necessario citare i riferimenti alle variabili. Cosa succede se qualcuno ha inserito un file con un carattere speciale nel tuo file di testo? Aggiungi una linea, "echo"; sudo rm -rf ~/">> testcurl.txt' e guarda cosa succede. – ghoti

+2

^Se non lo sai, non farlo. –

+1

Questa è una soluzione orribile; non solo genera un processo separato per ogni download, ma deve anche ristabilire la connessione TCP ogni volta, sprecando molto tempo anche su reti di media latenza. – cnst

1

Come altri hanno giustamente detto:

-cat urls.txt | xargs -0 curl -O 
+cat urls.txt | xargs -n1 curl -O 

Tuttavia, questo paradigma è una pessima idea, soprattutto se tutti gli URL provengono dallo stesso server - non sta solo andando a essere la deposizione delle uova un'altra istanza di arricciatura, ma stabilirà anche una nuova connessione TCP per ogni richiesta, che è altamente inefficiente, e ancora di più con l'https ormai onnipresente.

Utilizza questo invece:

-cat urls.txt | xargs -n1 curl -O 
+cat urls.txt | wget -i/dev/fd/0 

Oppure, ancora più semplice:

-cat urls.txt | wget -i/dev/fd/0 
+wget -i/dev/fd/0 < urls.txt 

più semplice ancora:

-wget -i/dev/fd/0 < urls.txt 
+wget -iurls.txt 
+2

L'OP era specificamente su come fare questo con arricciatura. Forse questo è per l'uso su un sistema in cui Curl è già installato ma wget non lo è, per esempio OSX. Inoltre, non è necessario dipendere da devfs, puoi anche usare '-i-' per fare riferimento a stdin. I.e .: 'wget -i- ghoti

17

Una soluzione molto semplice sarebbe il seguente: Se avere un file 'file.txt' come

url="http://www.google.de" 
url="http://www.yahoo.de" 
url="http://www.bing.de" 

Quindi è possibile utilizzare ricciolo e semplicemente fare

curl -K file.txt 

E ricciolo chiamerà tutti gli URL contenuti nel file.txt!

Quindi, se si ha il controllo sopra il vostro input-file di formato, forse questa è la soluzione più semplice per voi!

+0

Userà keep-alive HTTP? –

6

xargs -P 10 da GNU scarica i file in parallelo con un massimo di 10 thread:

xargs -P 10 -n 1 curl -O < urls.txt 

Questo accelererà scaricare 10x se la velocità massima di download, se non raggiunto e se il server non lo fa IP del throttle, che è lo scenario più comune.

Proprio non impostare -P troppo alto o la RAM può essere sopraffatti.

GNU parallel può ottenere risultati simili.

L'aspetto negativo di questi metodi è che essi non utilizzare una singola connessione per tutti i file, che cosa fa curl se si passa più URL ad esso in una volta, come in:

curl -O out1.txt http://exmple.com/1 -O out2.txt http://exmple.com/2 

come accennato https://serverfault.com/questions/199434/how-do-i-make-curl-use-keepalive-from-the-command-line

Forse che unisce entrambi i metodi avrebbero dato i migliori risultati?Ma immagino che la parallelizzazione sia più importante che mantenere viva la connessione.

Consulta anche: Parallel download using Curl command line utility

Problemi correlati