El patrón de reemplazo de expansión de parámetros zsh analiza la cadena de manera diferente si la entrada es una variable en lugar de estar en línea

El patrón de reemplazo de expansión de parámetros zsh analiza la cadena de manera diferente si la entrada es una variable en lugar de estar en línea

Un patrón de reemplazo de expansión de parámetros zsh analiza la cadena de manera diferente si la entrada es una variable en lugar de estar integrada.

Supongo que tiene algo que ver con el escape del personaje, pero no estoy seguro de cómo solucionarlo.

En el código siguiente, >& *debe 2.5.8filtrarse de la salida de printf, lo que ocurre en la primera expansión de parámetros usando la variable versions.

Pero cuando la curlllamada está en línea, los 3 valores anteriores no se filtran.

¿Cómo puedo insertar la curlllamada y aún así filtrar los 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:]]##}}

Respuesta1

Cite la $(command)sustitución:

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:]]##}

(Hubo uno adicional innecesario ${}alrededor de la expn, que se eliminó arriba)


En un zshshell predeterminado,expansión de parámetrosno necesita comillas para evitar dividir IFS(pero tampoco hará daño). No cotizadosustitución de comandoestá sujeto a división por IFS, por lo que se deben citar para evitarlo.

El manual zshexpn(1):

PARAMETER EXPANSION

Tenga en cuenta en particular el hecho de que las palabras de parámetros sin comillas no se dividen automáticamente en espacios en blanco a menos que SH_WORD_SPLITse establezca la opción; consulte las referencias a esta opción a continuación para obtener más detalles. Esta es una diferencia importante con respecto a otros caparazones. Sin embargo, como en otros shells, las palabras nulas se eliminan de las expansiones de parámetros sin comillas.

COMMAND SUBSTITUTION

Si la sustitución no está entre comillas dobles, la salida se divide en palabras utilizando el IFSparámetro.


Además, puede haber otras formas de eliminar esas cadenas, por ejemplo

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

que podría usarse con una sustitución de comando sin comillas:

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)}

Lo anterior utiliza una expansión de parámetros en el formulario ${name:#pattern}. El manual dice:

${name:#pattern}Si el patrón coincide con el valor del nombre, sustituya la cadena vacía; de lo contrario, simplemente sustituya el valor del nombre. Si el nombre es una matriz, los elementos coincidentes de la matriz se eliminan (use la (M)bandera para eliminar los elementos no coincidentes).

información relacionada