Utilizzo di xargs con input da un file


41

Di 'che ho un file con il seguente

bob
john
sue

Ora, questi direttamente corrospond a (in questo caso) modello URL, ad esempio http://example.com/persons/bob.tar, john.tar, sue.tar.

Vorrei prendere queste linee e percorrerle xargs. Tuttavia, non so cosa viene passato al comando in esecuzione. Come accedo al parametro o dal prompt (diciamo che voglio semplicemente fare eco ad ogni riga come cat file | xargs echo $PARAM) o da uno script bash.


Non sto seguendo la domanda, scusa. In particolare non sono sicuro di cosa significhi "Non so che cosa viene passato al comando da eseguire"
Michael Mrozek

1
@Michael: quando esegui un elenco, xargslo scompone per riga e inserisce ciascuna riga in un comando, giusto? Come posso accedervi se devo dire qualcosa del genere cat file | xargs curl http://example.com/[PASSED FROM FILE].tar?
Josh K,

Risposte:


70

La risposta di Michael è giusta e dovrebbe risolvere il tuo problema. In esecuzione

cat file | xargs -I % curl http://example.com/persons/%.tar

scaricherà i file bob.tar john.tar. sue.tarcome previsto.

MA : il gatto qui è inutile

piuttosto usare:

<file xargs -I % curl http://example.com/persons/%.tar

1
Nel mio esempio di un file potrebbe non essere l'ideale, comunque,cat xaa xab xac xad ... xargs ...
Josh K

10
@Josh Per qualche ragione le persone tendono a prendere davvero sul serio gli usi non necessari del gatto; Sono stato sottovalutato due volte per questo ora
Michael Mrozek

2
per la cronaca, hai ricevuto un +1 da me. Penso che usare catvada davvero bene, proprio come aggiungere ulteriori informazioni ... :)
Stefan,

Sicuramente dovrebbe essere xargs -I % curl …(l' opzione xargs prima curle le sue opzioni / argomenti). Per lo meno xargs curl -I %(dove -I %si intende un'opzione per xargs , non per arricciare ) non è portatile.
Chris Johnsen,

@Chris, bella cattura, grazie. fisso.
Stefan,

16

Penso che stai chiedendo come inserire le singole linee tratteggiate da xargs'stdin nel mezzo di un comando, invece di incollarlo sempre alla fine. In tal caso, la -Ibandiera accetta un replacement-stringargomento; xargssostituirà quindi replacement-stringnel comando con la riga letta da stdin:

$ cat file | xargs -I foobar curl http://example.com/foobar.tar

Va bene, che ne dici curl http://example.com/foobar.tar > foobar.tar?
Josh K,

2
@Josh K: >è un guscio costruito e non funzionerà xargs. D'altra parte, curl -oscriverà su un file con nome invece di stdout, come quello che wgetfa, quindi è probabilmente quello che vorresti usare qui.
effimero

9
$ man xargs
...
       --arg-file = File
       -un file
              Leggi gli elementi dal file anziché dallo standard input. Se lo usi
              opzione, stdin rimane invariato quando vengono eseguiti i comandi. Altro-
              saggia, lo stdin viene reindirizzato da / dev / null.
...

Si consiglia di set --delimiter=/ -da '\n'pure.


D'altra parte, se stai solo cercando di trasformare ogni riga del file in un URL,

$ sed -e 's #. * # http: //example.com/persons/&.tar#'

lo farà, e se vuoi prenderli tutti, basta inserirlo .| wget -i


8

un altro modo con shell looping:

for i in `cat file`; do curl -I http://foo.com/$i; done

puoi anche eseguire ogni iterazione in background aggiungendo &prima dell'ultimo punto e virgola - per download molto grandi potrebbe essere utile


2
Ti sei innamorato di uno dei classici errori ! <- link non funzionante, ecco una versione cache: Useless Use of Cat Award .
Sorpigal,

@Sorpigal Quell'URL è rotto. Cos'è il 'Classic Blunder'?
starbeamrainbowlabs

@starbeamrainbowlabs - uso inutile di cat, ho inserito una versione cache di quel link nel commento sopra.
slm

@starbeamrainbowlabs: in particolare mi stavo collegando a Dangerous Backticks , ma l'uso del gatto è anche inutile se cambi in un po 'di costruzione:while IFS= read i ; do curl ... ; done < file
Sorpigal


1

while read VAR; do ... done loop è semplice ma molto versatile:

while read word; do wget http://example.com/persons/$word; done < file

0

Questa è una versione più generale della risposta di Stefan: ma sto usando awk nel mezzo per preparare l'esatta "stringa" che vorrei eseguire xargs. E poi xargs sta usando bash per fare il vero "lavoro".

È un po 'eccessivo per questo esempio, ma è una soluzione generale che con alcune modifiche può risolvere molti problemi ...

cat file | awk '{print "curl http://example.com/persons/"$1".tar"}' | xargs -0 bash -c
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.