[[ ... ]] 中的 ZSH 扩展变量不执行通配符

问题描述 投票:0回答:2

我已将

extended_glob
设置为
.zshrc

这按预期工作:

[[ "value" = [a-z]* ]] && echo "globbed"

打印“globbed”。

但这并不:

foo=[a-z]*
[[ "value" = $foo ]] && echo "globbed"

不打印任何内容。
为什么会这样?我需要在 .zshrc 中设置什么(如果有的话)才能使其发挥作用?

pattern-matching zsh glob
2个回答
2
投票

你可以使用

foo='[a-z]*'
[[ "value" == $~foo ]] && echo "globbed"

$~foo
符号允许在 zsh 中进行通配。


0
投票

“为什么是[?]”

第一个代码示例:模式is已识别

[[ "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.

“我需要在 .zshrc 中设置什么(如果有的话)才能使其发挥作用?”

您可以使用

$~VARIABLE
形式,如上所述和另一个答案,或者您可以在
GLOB_SUBST
中设置
~/.zshrc
选项:

setopt GLOB_SUBST


注意:术语 globbing模式

您使用的实际上并不是globbing。您正在使用模式,更具体地说,您正在使用模式进行文本匹配。这有时被称为“模式匹配” - 但我更喜欢避免使用该术语,因为它在一般编程上下文中用于其他内容。

Globbing,zsh 手册称之为文件名生成(bash 称之为路径名扩展),是使用模式来扩展到匹配文件

模式也用于匹配文本,就像在您的代码中一样 - 但这不是“通配符”。


为了混淆事情,zsh 手册在“扩展”下记录了模式的语法和逻辑 - 无论是用于文件名生成还是文本匹配; “文件名生成”。该部分有诸如“通配标志”之类的小节——它们确实用于通配,但也用于字符串匹配上下文中的模式。还可以注意到,例如的描述本小节中的

b
标志如其第二句所示:“...这在文件名生成中不起作用。”因此,这里我们有一个只能用于文本匹配的构造,不能用于“文件名生成”部分中指定的文件名生成。

© www.soinside.com 2019 - 2024. All rights reserved.