Em zsh
, com a expansão glob, podemos usar o P
sinalizador para preceder cada correspondência com algum texto:
$ ls -1
bar
baz
foo
$ print -- *(P:--file:)
--file bar --file baz --file foo
Existe algo análogo para parâmetros de matriz? Se eu escrever
items=(foo bar baz)
existe algum sinalizador que eu possa usar para obter um comportamento como esse?
$ print -- ${(...)items}
--file foo --file bar --file baz
A melhor resposta depende do que você precisa da matriz modificada.
Se você estiver gerando argumentos de linha de comando (como na pergunta) e estiver usando uma ferramenta que aceita sinalizadores como
--file=foo
como alternativa a--file foo
, a abordagem mais idiomática é usar a${^name}
forma de expansão:Estou usando
print -lr
para demonstrar que a expansão produz um array com três elementos. Se você chamar um comando como este, o comando verá três argumentos.Se você estiver gerando argumentos de linha de comando, você pode colocar o texto para preceder (
--file
neste exemplo) em um array fictício e combiná-lo com o array de argumentos usando a${name:^^arrayname}
forma de expansão:Esta é uma matriz com seis elementos. Este formato ou aquele em (1)—ou ambos—deve ser aceitável para praticamente qualquer ferramenta de linha de comando para passar sinalizadores com valores associados.
Você pode modificar a abordagem em (1) para usar um espaço em vez de um sinal de igual:
(Observe que você tem que escapar do espaço com uma barra invertida; usar aspas duplas como
"--file ${^items}"
significa outra coisa.) Este é um array com três elementos, mas com um espaço embutido em cada elemento. Poucas ferramentas de linha de comando aceitam sinalizadores nesse formato, mas podem ser úteis para outros tipos de manipulação de texto.Você também pode usar a
${name/pattern/repl}
forma de expansão. O padrão deve começar com#
(para indicar que ele precisa corresponder no início de cada elemento da matriz), mas, caso contrário, deve estar vazio (para que todos os elementos da matriz correspondam e nenhum texto seja realmente substituído).Isso tem as mesmas ressalvas que (3) e também é menos idiomático do que essa abordagem.
Observe que todas essas quatro abordagens farão a coisa certa (ou seja, elas não dividirão repentinamente strings em espaços) quando os elementos do array contiverem espaços.
Você pode usar o
P
modificador glob! Tudo pode ser um globo se você insistir. Note que eu não estou dizendo que eu realmente gostaria de fazer isso. Não consigo pensar em uma situação em que seja a melhor maneira. Mas é tecnicamente possível.Ele funciona criando um glob que corresponde exatamente a um nome de arquivo (
/
funciona bem), usando o qualificador globe
para substituir a correspondência por uma lista arbitrária e aplicando oP
qualificador ao resultado.Isso só funciona em contextos em que o globbing é executado, mas geralmente é um caso em que uma matriz é permitida.
Você pode fazer isso de forma portátil (ou, pelo menos, portátil para shells que suportam essa sintaxe de matriz) com
printf
:Ao contrário do
print
comando, no entanto, isso não adiciona uma nova linha à direita (e é por isso que você tem o$
na mesma linha que a saída, acima). Se isso for um disjuntor, você pode fazer: