Sé que, teniendo en cuenta l="a b c"
,
echo $l | xargs ls
rendimientos
ls a b c
¿Qué construcción produce
mycommand -f a -f b -f c
Sé que, teniendo en cuenta l="a b c"
,
echo $l | xargs ls
rendimientos
ls a b c
¿Qué construcción produce
mycommand -f a -f b -f c
Respuestas:
Una forma de hacerlo:
echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand
Esto supone a
, b
y c
no contiene espacios en blanco, nuevas líneas, comillas o barras diagonales inversas. :)
Con GNU findutil
puedes manejar el caso general, pero es un poco más complicado:
echo -n "a|b|c" | tr \| \\0 | xargs -0 printf -- '-f\0%s\0' | xargs -0 mycommand
Puede sustituir el |
separador con algún otro carácter, que no aparece en a
, b
o c
.
Editar: como señala @MichaelMol , con una lista muy larga de argumentos existe el riesgo de desbordar la longitud máxima de argumentos a los que se puede pasar mycommand
. Cuando eso sucede, el último xargs
dividirá la lista y ejecutará otra copia de mycommand
, y existe el riesgo de que deje un no terminado -f
. Si te preocupa esa situación, puedes reemplazar el último xargs -0
anterior por algo como esto:
... | xargs -x -0 mycommand
Esto no resolverá el problema, pero abortará la ejecución mycommand
cuando la lista de argumentos sea demasiado larga.
mycommand
. Siempre puedes agregar -x
al último xargs
.
xargs
en absoluto, y solo usarla find
si puede usarse. Esta solución es peligrosa; al menos debe advertir el caso de falla en su respuesta.
find
sería una mejor solución general, particularmente cuando los argumentos iniciales no son nombres de archivo. :)
-f
, y con una herramienta de ejemplo ls
utilizada para ilustración, @ not-a-user está tratando con nombres de archivos. Y dado find
ofrece el -exec
argumento, que le permite construir una línea de comandos, está bien. (Siempre y cuando mycommand
se permita ejecutar más de una vez. Si no es así, entonces tenemos otro problema con el uso de xargs
aquí ...)
Una mejor manera de abordarlo (IMO) sería:
en zsh
:
l=(a b c)
mycommand -f$^l
o usando la compresión de la matriz para que el argumento no se adjunte a la opción:
l=(a b c) o=(-f)
mycommand "${o:^^l}"
De esa manera, todavía funciona si la l
matriz contiene elementos vacíos o elementos que contienen espacios o cualquier otro carácter problemático para xargs
. Ejemplo:
$ l=(a '' '"' 'x y' c) o=(-f)
$ printf '<%s>\n' "${o:^^l}"
<-f>
<a>
<-f>
<>
<-f>
<">
<-f>
<x y>
<-f>
<c>
en rc
:
l=(a b c)
mycommand -f$l
en fish
:
set l a b c
mycommand -f$l
(AFAIK, rc
y fish
no tiene compresión de matriz)
Con conchas de estilo Bourne de estilo antiguo como bash
, siempre puedes hacer (aún permitiendo cualquier carácter en los elementos de la $@
matriz):
set -- a b c
for i do set -- "$@" -f "$i"; shift; done
mycommand "$@"
for i; do args+=('-f' "$i");done;
mycommand "${args[@]}"
. IDK si esto es más rápido, pero agregar 2 elementos a una matriz parece que debería ser O (n), mientras que su set
ciclo probablemente copia y vuelve a analizar la lista de argumentos acumulados cada vez (O (n ^ 2)).
ARG_MAX
y tener un-f
parámetro separado de su par.