我已将
extended_glob
设置为 .zshrc
。
这按预期工作:
[[ "value" = [a-z]* ]] && echo "globbed"
打印“globbed”。
但这并不:
foo=[a-z]*
[[ "value" = $foo ]] && echo "globbed"
不打印任何内容。
为什么会这样?我需要在 .zshrc 中设置什么(如果有的话)才能使其发挥作用?
你可以使用
foo='[a-z]*'
[[ "value" == $~foo ]] && echo "globbed"
$~foo
符号允许在 zsh 中进行通配。
[[ "value" = [a-z]* ]] && echo "globbed"
# prints "globbed"
# (regardless of whether GLOB_SUBST is set or not)
因为:
一般来说:未加引号的模式元字符,例如
*
、用于模式匹配(在允许的上下文中)。 在 zsh 手册中,针对每个用例/上下文分别记录了这一点。
特别针对上述条件: 对于
a
中的 [[ .. = a ]]
,其行为遵循上面给出的一般准则。 在 zsh 手册中,这在“条件表达式”部分中有记录:本例中的形式为 string = pattern
,手册中指出:
模式元字符对 pattern 参数有效
foo=[a-z]*
[[ "value" = $foo ]] && echo "globbed"
# prints nothing
# (if GLOB_SUBST is unset, which is the default)
因为:在 zsh 中,扩展/替换的结果被视为文字字符,而不是模式元字符。 在 zsh 手册中,这记录在“扩展”部分的“参数扩展”下:
${~spec} ${~~spec} Turn on the GLOB_SUBST option for the evaluation of spec; if the `~' is doubled, turn it off. When this option is set, the string resulting from the expansion will be interpreted as a pattern anywhere that is possible, such as in filename expansion and filename generation and pattern-matching contexts like the right hand side of the `=' and `!=' operators in conditions.
您可以使用
$~VARIABLE
形式,如上所述和另一个答案,或者您可以在 GLOB_SUBST
中设置 ~/.zshrc
选项:
setopt GLOB_SUBST
您使用的实际上并不是globbing。您正在使用模式,更具体地说,您正在使用模式进行文本匹配。这有时被称为“模式匹配” - 但我更喜欢避免使用该术语,因为它在一般编程上下文中用于其他内容。
Globbing,zsh 手册称之为文件名生成(bash 称之为路径名扩展),是使用模式来扩展到匹配文件。
模式也用于匹配文本,就像在您的代码中一样 - 但这不是“通配符”。
为了混淆事情,zsh 手册在“扩展”下记录了模式的语法和逻辑 - 无论是用于文件名生成还是文本匹配; “文件名生成”。该部分有诸如“通配标志”之类的小节——它们确实用于通配,但也用于字符串匹配上下文中的模式。还可以注意到,例如的描述本小节中的
b
标志如其第二句所示:“...这在文件名生成中不起作用。”因此,这里我们有一个只能用于文本匹配的构造,不能用于“文件名生成”部分中指定的文件名生成。