O padrão de substituição de expansão de parâmetro zsh analisa a string de maneira diferente se a entrada for uma variável em vez de embutida

O padrão de substituição de expansão de parâmetro zsh analisa a string de maneira diferente se a entrada for uma variável em vez de embutida

Um padrão de substituição de expansão de parâmetro zsh analisa a string de maneira diferente se a entrada for uma variável em vez de embutida.

Presumo que tenha algo a ver com a fuga do personagem, mas não tenho certeza de como contornar isso.

No código abaixo, >, *& 2.5.8deve ser filtrado da saída printf, que ocorre na primeira expansão do parâmetro usando a variável versions.

Mas quando a curlchamada está embutida, os 3 valores acima não são filtrados.

Como posso incorporar a curlchamada e ainda assim filtrar os 3 valores?

#!/usr/bin/env zsh

setopt EXTENDED_GLOB

# variable: 3 values are correctly filtered out
versions=$(curl '--silent' '--location' 'https://api.sdkman.io/2/candidates/groovy/darwin/versions/list?current=2.5.8&installed=2.5.8')
printf -- '%s\n' ${${(Z+n+)versions//[*+>][ *+>]# [[:graph:]]##}}

# inlined: 3 values are not filtered out
printf -- '%s\n' ${${(Z+n+)$(curl '--silent' '--location' 'https://api.sdkman.io/2/candidates/groovy/darwin/versions/list?current=2.5.8&installed=2.5.8')//[*+>][ *+>]# [[:graph:]]##}}

Responder1

Cite a $(command)substituição:

printf -- '%s\n' ${(Z+n+)"$(curl '--silent' '--location' 'https://api.sdkman.io/2/candidates/groovy/darwin/versions/list?current=2.5.8&installed=2.5.8')"//[*+>][ *+>]# [[:graph:]]##}

(Havia um extra desnecessário ${}em torno da expn, que foi removido acima)


Em um zshshell padrão,expansão de parâmetrosnão precisa de citação para evitar divisão IFS(mas também não vai doer). Sem citaçãosubstituição de comandoestá sujeito a divisão por IFS, portanto, é necessário fazer citações para evitar isso.

O manual zshexpn(1):

PARAMETER EXPANSION

Observe em particular o fato de que palavras com parâmetros sem aspas não são automaticamente divididas em espaços em branco, a menos que a opção SH_WORD_SPLITseja definida; veja as referências a esta opção abaixo para obter mais detalhes. Esta é uma diferença importante em relação a outros shells. No entanto, como em outros shells, palavras nulas são omitidas das expansões de parâmetros sem aspas.

COMMAND SUBSTITUTION

Se a substituição não estiver entre aspas duplas, a saída será dividida em palavras usando o IFSparâmetro.


Além disso, pode haver outras maneiras de remover essas strings, por exemplo

printf -- '%s\n' ${${=versions}:#([*+>-]|2.5.8)}

que poderia ser usado com uma substituição de comando sem aspas:

printf -- '%s\n' ${$(curl '--silent' '--location' 'https://api.sdkman.io/2/candi'\
'dates/groovy/darwin/versions/list?current=2.5.8&installed=2.5.8'):#([*+>-]|2.5.8)}

O texto acima usa uma expansão de parâmetro no formato ${name:#pattern}. O manual diz:

${name:#pattern}Se o padrão corresponder ao valor de name, substitua a string vazia; caso contrário, basta substituir o valor do nome. Se name for um array, os elementos correspondentes do array serão removidos (use o (M)sinalizador para remover os elementos não correspondentes).

informação relacionada