Bash 扩展 glob 模式否定在参数替换中不起作用

Bash extended glob pattern negation is not working in parameter substitution

提问人:XDR 提问时间:9/4/2023 更新时间:9/4/2023 访问量:79

问:

Bash 3.2.57(在 macOS 12.6.8 上)扩展的 glob 模式否定在参数替换中不起作用:

$ shopt -s extglob
$ s=abc
$ echo ${s##!(a)*}

我希望最后一个命令输出,但它没有输出任何东西。abc

如果第一个字符不是,我怎样才能使第三行不输出任何内容,但如果第一个字符是,则输出?$s'a'$s'a'

正则表达式 bash glob 参数扩展 extglob

评论

1赞 Barmar 9/4/2023
仅供参考,Linux 上的 5.1.4 中也发生了同样的事情。
2赞 Barmar 9/4/2023
如果只需要匹配第一个字符,则可以使用${s##[^a]*}
6赞 Philippe 9/4/2023
这应该有效:echo ${s##!(a*)}
0赞 Nahuel Fouilleul 9/4/2023
!(a)比赛:abc[[ abc = !(a) ]] && echo matches

答:

2赞 pynexj 9/4/2023 #1

$ shopt -s extglob
$ [[ abc == a!(b)c ]] && echo yes || echo no
no
$ [[ ac == a!(b)c ]] && echo yes || echo no
yes

并从:man bash

  • !(pattern-list)

    匹配除给定模式之一之外的任何内容

所以这里的任何东西都可以是空字符串。(我认为 Bash 的手册可以更明确地说明这一点。

评论

0赞 XDR 9/4/2023
如果它可以匹配 null 字符串,那么它就相当无用了。
0赞 Paul Hodges 9/4/2023 #2

如果$s的第一个字符不是“a”,我怎样才能使第三行不输出任何内容,但如果第一个字符是“a”,则输出$s?

case $s in a*) echo $s;; esac  # conditional execution

[[ $s =~ ^a ]] && echo $s      # conditional execution

[[ ${s:0:1} == a ]] && echo $s # conditional execution

或者,更像是你尝试过的,

echo ${s/#[^a]*/}              # string parsed to scrub nonmatch

不需要扩展通配。