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.