Usar xargs con entrada de un archivo


41

Digamos que tengo un archivo con lo siguiente

bob
john
sue

Ahora bien, estos directamente a corrospond (en este caso) patrón de URL como http://example.com/persons/bob.tar, john.tar, sue.tar.

Me gustaría tomar estas líneas y recorrerlas xargs. Sin embargo, no sé qué se pasa al comando que se ejecuta. ¿Cómo accedo al parámetro desde el indicador (por ejemplo, quiero hacer eco de cada línea cat file | xargs echo $PARAM) o desde un script bash?


No estoy siguiendo la pregunta, lo siento. En particular, no estoy seguro de lo que significa "No sé qué se pasa al comando que se está ejecutando"
Michael Mrozek

1
@Michael: Cuando ejecuta una lista xargs, la divide por línea y alimenta cada línea en un comando, ¿verdad? ¿Cómo accedo a eso si necesito decir algo como cat file | xargs curl http://example.com/[PASSED FROM FILE].tar?
Josh K

Respuestas:


70

La respuesta de Michael es correcta, y debería resolver su problema. Corriendo

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

descargará los archivos bob.tar john.tar. sue.tarcomo se esperaba.

PERO : el gato aquí es inútil

prefiero usar:

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

1
Sin embargo, en mi ejemplo de un archivo puede no ser idealcat xaa xab xac xad ... xargs ...
Josh K

10
@Josh Por alguna razón, la gente tiende a tomar en serio los usos innecesarios del gato aquí; Me han votado en contra dos veces
Michael Mrozek

2
para que conste, obtuviste un +1 de mi parte. Creo que usar catestá bien, solo quiero agregar más información ... :)
Stefan

Seguramente debería ser xargs -I % curl …( opción xargs antes curly sus opciones / argumentos). Por lo menos xargs curl -I %(donde -I %se entiende como una opción para xargs , no curl ) no es portátil.
Chris Johnsen

@ Chris, buena captura, tnx. fijo.
Stefan

16

Creo que está preguntando cómo insertar las líneas individuales extraídas de xargs'stdin en el medio de un comando, en lugar de pegarlo siempre al final. Si es así, la -Ibandera toma un replacement-stringargumento; xargsluego reemplazará replacement-stringen el comando con la línea leída de stdin:

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

Ok, que tal curl http://example.com/foobar.tar > foobar.tar?
Josh K

2
@ Josh K: >es una construcción de shell, y no funcionará xargs. Por otro lado, curl -oescribirá en un archivo con nombre en lugar de stdout, como lo que wgethace, por lo que probablemente sea lo que le gustaría usar aquí.
Ephemient

9
$ man xargs
...
       --arg-file = archivo
       -un archivo
              Leer elementos del archivo en lugar de la entrada estándar. Si usas esto
              opción, stdin permanece sin cambios cuando se ejecutan los comandos. Otro-
              sabio, stdin se redirige desde / dev / null.
...

Es posible que desee establecer --delimiter=/ -da '\n'también.


Por otro lado, si solo está tratando de convertir cada línea del archivo en una URL,

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

servirá, y si quieres buscarlos todos, simplemente mételos .| wget -i


8

Otra forma con el bucle de shell:

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

también puede ejecutar cada iteración en segundo plano agregando &antes del último punto y coma; para descargas muy grandes, esto podría ser útil


2
¡Te has enamorado de uno de los errores clásicos ! <- enlace roto, aquí hay una versión en caché: Uso Inútil del Premio Cat .
Sorpigal

@Sorpigal Esa url está rota. ¿Qué es el 'error clásico'?
starbeamrainbowlabs

@starbeamrainbowlabs: uso inútil de cat, he puesto una versión en caché de ese enlace en el comentario anterior.
slm

@starbeamrainbowlabs: específicamente me estaba vinculando a Dangerous Backticks , pero el uso de cat también es innecesario si cambias a una construcción while IFS= read i ; do curl ... ; done < file
temporal


1

while read VAR; do ... done El bucle es simple pero muy versátil:

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

0

Esta es una versión más general de la respuesta de Stefan, pero estoy usando awk en el medio para preparar la "cadena" exacta que me gustaría que ejecutara xargs. Y luego xargs está usando bash para hacer el "trabajo" real.

Es un poco exagerado para este ejemplo, pero es una solución general que con algunas modificaciones puede resolver muchos problemas ...

cat file | awk '{print "curl http://example.com/persons/"$1".tar"}' | xargs -0 bash -c
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.