假设你有类似的东西:
$ a=(fooa foob foox)
然后你可以这样做:
$ b=(${(M)a:#*(a|b)})
选择与模式匹配的元素。
所以你有:
$ print ${(qq)b}
'fooa' 'foob'
然后你希望以某种动态方式构建模式,所以你将它放在另一个变量中,比如说:
$ p="*(a|b)"
你期待这个:
$ b=(${(M)a:#$p})
正如文档所述,它将像以前一样工作,但它不会:
$ print ${(qq)b}
''
为什么?
答案 0 :(得分:0)
因为在这种情况下zsh试图逐字地选择$p
的值(纯字符串文本):
a=('*(a|b)' fooa foob)
p="*(a|b)"
b=(${(M)a:#$p})
print ${(qq)b}
;#⇒'*(a|b)'
我们可以告诉zsh将$p
的扩展视为模式而不是${~spec}
形式明确的文字值。
$ {〜规范}
启用
GLOB_SUBST
选项以评估规范;如果“~
”加倍,请将其关闭。设置此选项后,扩展产生的字符串将被解释为任何可能的模式,例如文件名扩展和文件名生成以及模式匹配上下文(如“=
”的右侧)条件中的'!=
'运营商。
在这种情况下,我们可以像这样使用它:
a=(fooa foob foox)
p="*(a|b)"
b=(${(M)a:#${~p}}) ;# tell zsh treat as a pattern for `$p`
print ${(qq)b}
;#⇒'fooa' 'foob'
注意:它在参数扩展标志b
中提供了一些提示,用于在变量值中存储模式:
b
使用反斜杠引用仅对模式匹配特殊的字符。当使用
GLOB_SUBST
(包括${~...}
开关)测试变量的内容时,此功能非常有用。使用q系列标志之一进行引用不能用于此目的,因为引号不会被
GLOB_SUBST
从非模式字符中删除。换句话说,如果pattern=${(q)str} [[ $str = ${~pattern} ]]
$str
为“a*b
”,则有效,但如果为“
a b
”则无效,而对于pattern=${(b)str} [[ $str = ${~pattern} ]]
$str
的任何可能值,始终为真。
-
zshexpn(1): Expansion, Parameter Expansion, Parameter Expansion Flags