Eu sei que, dado l="a b c"
,
echo $l | xargs ls
rendimentos
ls a b c
Qual construção produz
mycommand -f a -f b -f c
Eu sei que, dado l="a b c"
,
echo $l | xargs ls
rendimentos
ls a b c
Qual construção produz
mycommand -f a -f b -f c
Respostas:
Uma maneira de fazer isso:
echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand
Isso pressupõe a
, b
e c
não contém espaços em branco, novas linhas, aspas ou barras invertidas. :)
Com o GNU, findutil
você pode lidar com o caso geral, mas é um pouco mais complicado:
echo -n "a|b|c" | tr \| \\0 | xargs -0 printf -- '-f\0%s\0' | xargs -0 mycommand
Você pode substituir o |
separador com algum outro personagem, que não aparece em a
, b
ou c
.
Editar: Como observa o @MichaelMol , com uma lista muito longa de argumentos, existe o risco de exceder o tamanho máximo dos argumentos que podem ser passados mycommand
. Quando isso acontece, o último xargs
dividirá a lista e executará outra cópia de mycommand
, e existe o risco de deixar um não terminado -f
. Se você se preocupar com essa situação, poderá substituir o último xargs -0
acima por algo assim:
... | xargs -x -0 mycommand
Isso não resolverá o problema, mas interromperá a execução mycommand
quando a lista de argumentos for muito longa.
mycommand
. Você sempre pode adicionar -x
ao último xargs
.
xargs
, e use apenas find
se puder ser usada. Essa solução é perigosa; você deve pelo menos avisar sobre o caso de falha em sua resposta.
find
seria uma solução geral melhor, principalmente quando os argumentos iniciais não são nomes de arquivos. :)
-f
e uma ferramenta de exemplo ls
usada para ilustração, @ não-usuário lida com nomes de arquivos. E, como find
oferece o -exec
argumento, que permite construir uma linha de comando, tudo bem. (Contanto que mycommand
seja permitido executar mais de uma vez. Se não for, teremos outro problema com o uso xargs
aqui ...) #
Uma maneira melhor de resolvê-lo (IMO) seria:
em zsh
:
l=(a b c)
mycommand -f$^l
ou usando o zip da matriz para que o argumento não seja anexado à opção:
l=(a b c) o=(-f)
mycommand "${o:^^l}"
Dessa forma, ainda funcionará se a l
matriz contiver elementos vazios ou elementos que contenham espaços ou qualquer outro caractere problemático xargs
. Exemplo:
$ l=(a '' '"' 'x y' c) o=(-f)
$ printf '<%s>\n' "${o:^^l}"
<-f>
<a>
<-f>
<>
<-f>
<">
<-f>
<x y>
<-f>
<c>
em rc
:
l=(a b c)
mycommand -f$l
em fish
:
set l a b c
mycommand -f$l
(AFAIK rc
e fish
não possui zíper na matriz)
Com cascas de estilo Bourne do estilo antigo bash
, você sempre pode fazer (ainda permitindo qualquer caractere nos elementos da $@
matriz):
set -- a b c
for i do set -- "$@" -f "$i"; shift; done
mycommand "$@"
for i; do args+=('-f' "$i");done;
mycommand "${args[@]}"
. IDK se for mais rápido, mas anexar 2 elementos a uma matriz parece que deve ser O (n), enquanto seu set
loop provavelmente copia e analisa a lista de argumentos acumulados todas as vezes (O (n ^ 2)).
ARG_MAX
e-f
separar seu parâmetro emparelhado.