Shell 为什么这种内部扩展模式不起作用?
假设您有如下内容:Shell 为什么这种内部扩展模式不起作用?,shell,scripting,zsh,variable-expansion,Shell,Scripting,Zsh,Variable Expansion,假设您有如下内容: $ a=(fooa foob foox) 然后你可以做: $ b=(${(M)a:#*(a|b)}) 选择与阵列匹配的阵列元素 所以你有: $ print ${(qq)b} 'fooa' 'foob' 然后您希望以某种动态方式构建模式,因此您可以将其放在另一个变量中,例如: $ p="*(a|b)" 你希望这样: $ b=(${(M)a:#$p}) 正如文档所述,它的工作原理与以前相同
$ a=(fooa foob foox)
然后你可以做:
$ b=(${(M)a:#*(a|b)})
选择与阵列匹配的阵列元素
所以你有:
$ print ${(qq)b}
'fooa' 'foob'
然后您希望以某种动态方式构建模式,因此您可以将其放在另一个变量中,例如:
$ p="*(a|b)"
你希望这样:
$ b=(${(M)a:#$p})
正如文档所述,它的工作原理与以前相同,但它没有:
$ print ${(qq)b}
''
为什么会这样?因为在本例中,zsh试图以纯字符串文本的形式选择$p的值: a='*a | b'fooa foob p=*a | b b=${Ma:$p} 打印${qqb} ;⇒'*a | b' 我们可以告诉zsh将$p的扩展视为模式,而不是通过${~spec}形式显式地处理文字值 ${~spec} 启用用于评估等级库的选项;如果“~”加倍,请将其关闭。设置此选项后,扩展产生的字符串将被解释为任何可能的模式,例如在文件名扩展和文件名生成以及模式匹配上下文(如“=”和“!=”的右侧)中操作人员处于危险状态 - 在这种情况下,我们可以这样使用它: a=fooafoobfoox p=*a | b b=${Ma:${~p};告诉zsh将其视为“$p”的模式` 打印${qqb} ;⇒'fooa“foob” 注意:它在参数扩展标志b中给出了一些提示,用于将模式存储在变量值中: b 仅对模式匹配专用的字符使用反斜杠引号。这在使用${~…}开关测试变量内容时非常有用 使用q系列标志之一的引号不适用于此目的,因为引号不会从非模式字符中删除。换句话说,
pattern=${(q)str}
[[ $str = ${~pattern} ]]
如果$str是'a*b',则有效,但如果它是'a b',则无效
pattern=${(b)str}
[[ $str = ${~pattern} ]]
对于$str的任何可能值,都始终为true
-