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

发布于 2025-01-14 20:34:50 字数 327 浏览 3 评论 0原文

我在 .zshrc 中设置了 extended_glob

这按预期工作:

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

打印“globbed”。

但这不会:

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

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

I have extended_glob set in .zshrc.

This works as expected:

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

Prints "globbed".

But this does not:

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

Doesn't print anything.
Why is that and what do I need to set, if anything, in .zshrc to make it function?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

穿透光 2025-01-21 20:34:50

您可以使用

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

$~foo 表示法允许在 zsh 中进行通配。

You can use

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

$~foo notation allows globbing in zsh.

拥抱影子 2025-01-21 20:34:50

“为什么是[?]”

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

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

# prints "globbed"
# (regardless of whether GLOB_SUBST is set or not)

因为:

一般来说:不带引号的模式元字符,例如< code>*、 用于模式匹配(在允许的上下文中)。 在 zsh 手册中,针对每个用例/上下文分别记录了这一点。

特别是对于上述条件:对于 [[ .. = a ]] 中的 a,其行为遵循上面给出的一般准则。 在 zsh 手册中,这在“条件表达式”部分中进行了记录:本例中的形式为 string = pat,手册中指出:

模式元字符对模式参数有效

第二个代码示例:模式未被识别

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

# prints nothing
# (if GLOB_SUBST is unset, which is the default)

因为:在zsh中,扩展/替换的结果是被视为文字字符,而不是模式元字符。 在 zsh 手册中,这记录在“扩展”部分的“参数扩展”下:

<前><代码>${~规格}
${~~规格}
打开GLOB_SUBST选项来评估spec;如果
‘~’加倍,关掉它。当设置该选项时,
扩展产生的字符串将被解释为
任何可能的地方的模式,例如在文件名扩展中
以及文件名生成和模式匹配上下文,例如
条件中“=”和“!=”运算符的右侧。

“如果有的话,我需要在 .zshrc 中设置什么才能使其正常工作?”

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

setopt GLOB_SUBST


注意:术语通配模式

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

Globbing,zsh 手册将其称为文件名生成(bash 将其称为路径名扩展),是使用模式进行扩展以匹配文件。

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


令人困惑的是,zsh 手册在“扩展”下记录了模式的语法和逻辑 - 无论是用于文件名生成还是文本匹配; “文件名生成”。该部分有诸如“通配标志”之类的小节——它们确实用于通配,但也用于字符串匹配上下文中的模式。还可以注意到,本小节中的 b 标志的描述如其第二句所述:“...这在文件名生成中不起作用。”因此,这里我们有一个只能用于文本匹配的构造,不能用于“文件名生成”部分中指定的文件名生成。

"Why is that [?]"

First code example: pattern is recognized

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

# prints "globbed"
# (regardless of whether GLOB_SUBST is set or not)

Because:

In general: unquoted pattern meta-characters, such as *, are used for pattern matching (in contexts that allow it). In the zsh manual, this is documented separately for each use case/context.

Specifically for the conditional above: for a in [[ .. = a ]], the behaviour follows the general guideline given above. In the zsh manual, this is documented in the "Conditional Expressions" section: the form in this case is string = pattern, for which the manual states:

Pattern metacharacters are active for the pattern arguments

Second code example: pattern is not recognized

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

# prints nothing
# (if GLOB_SUBST is unset, which is the default)

Because: in zsh, the result of an expansion/substitution is treated as literal characters, not as pattern metacharacters. In the zsh manual, this is documented under the "Expansions" section, under "Parameter Expansion":

${~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.

"what do I need to set, if anything, in .zshrc to make it function?"

You can use the $~VARIABLE form, as described above and in another answer, or you can set the GLOB_SUBST option in ~/.zshrc:

setopt GLOB_SUBST


Note: terminology globbing vs. patterns

What you are using is not actually globbing. You are using patterns, and more specifically, you are using patterns for text matching. This is sometimes referred to as "pattern matching" - however I prefer to avoid that term since it is used for something else in general programming contexts.

Globbing, which the zsh manual calls Filename generation (bash calls it Pathname expansion), is the use of patterns for expanding to matching files.

Patterns are also used for matching text, as in your code - but this is not "globbing".


To confuse things, the zsh manual documents the syntax and logic for patterns - whether it is used for filename generation or text matching - under "Expansions"; "Filename Generation". That section has subsections such as "Globbing flags" - which are indeed used for globbing, but also for patterns in string matching contexts. It can also be noted that the description of e.g. the b flag in this subsection states, as its second sentence: "...this does not work in filename generation." So here we have a construct that can only be used for text matching, not Filename Generation, specified in the section "Filename Generation".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文