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, be cnão contém espaços em branco, novas linhas, aspas ou barras invertidas. :)
Com o GNU, findutilvocê 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, bou 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 xargsdividirá 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 -0acima por algo assim:
... | xargs -x -0 mycommand
Isso não resolverá o problema, mas interromperá a execução mycommandquando a lista de argumentos for muito longa.
mycommand. Você sempre pode adicionar -xao último xargs.
xargs, e use apenas findse puder ser usada. Essa solução é perigosa; você deve pelo menos avisar sobre o caso de falha em sua resposta.
findseria uma solução geral melhor, principalmente quando os argumentos iniciais não são nomes de arquivos. :)
-fe uma ferramenta de exemplo lsusada para ilustração, @ não-usuário lida com nomes de arquivos. E, como findoferece o -execargumento, que permite construir uma linha de comando, tudo bem. (Contanto que mycommandseja permitido executar mais de uma vez. Se não for, teremos outro problema com o uso xargsaqui ...) #
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 lmatriz 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$lem fish:
set l a b c
mycommand -f$l(AFAIK rce fishnã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 setloop provavelmente copia e analisa a lista de argumentos acumulados todas as vezes (O (n ^ 2)).
ARG_MAXe-fseparar seu parâmetro emparelhado.