如果输入是变量而不是内联,zsh 参数扩展替换模式会以不同的方式解析字符串

如果输入是变量而不是内联,zsh 参数扩展替换模式会以不同的方式解析字符串

如果输入是变量而不是内联变量,则 zsh 参数扩展替换模式会以不同的方式解析字符串。

我认为这与字符转义有关,但不知道如何解决它。

在下面的代码中,>, *&2.5.8应该从 printf 输出中过滤掉,这发生在使用变量 的第一个参数扩展中versions

但是当curl调用是内联的时候,上面的3个值就不会被过滤掉。

如何内联调用curl但仍过滤掉 3 个值?

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

答案1

引用$(command)替换:

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

${}( expn 周围有一个多余的多余部分,已在上面删除)


在默认zshshell 中,参数扩展不需要引用来避免分裂IFS(但这也不会造成伤害)。不加引号命令替换会被 分割IFS,因此必须引用以避免这种情况。

手册zshexpn(1)

PARAMETER EXPANSION

SH_WORD_SPLIT特别要注意的是,除非设置了该选项,否则未加引号的参数的单词不会自动在空格上分割;有关更多详细信息,请参阅下面对此选项的引用。这是与其他 shell 的一个重要区别。然而,与其他 shell 一样,未加引号的参数扩展中会忽略空字。

COMMAND SUBSTITUTION

如果替换未用双引号括起来,则使用参数将输出分解为单词IFS


此外,可能还有其他方法可以删除这些字符串,例如

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

可以与不带引号的命令替换一起使用:

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

上面使用了形式的参数扩展${name:#pattern}。手册说:

${name:#pattern}如果模式与 name 的值匹配,则替换为空字符串;否则,只需替换 name 的值即可。如果 name 是一个数组,则删除匹配的数组元素(使用该(M)标志删除不匹配的元素)。

相关内容