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.8
filtrarse de la salida de printf, lo que ocurre en la primera expansión de parámetros usando la variable versions
.
Pero cuando la curl
llamada está en línea, los 3 valores anteriores no se filtran.
¿Cómo puedo insertar la curl
llamada 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 zsh
shell 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_SPLIT
se 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
IFS
pará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).