extglob 如何使用 shell 参数扩展?

How does extglob work with shell parameter expansion?

我以为我理解 ?(pattern-list)bash (when extglob shell option is on) and by default in ksh 中的用法。例如 bash:

$ shopt -s extglob
$ V=35xAB
$ echo "${V#?(35|88)x}" "${V#35}"
AB xAB

但是当匹配前缀模式只是一个?()或一个*()时,这就引入了我所说的可选模式,除非使用##,否则不会省略35

$ echo "${V#?(35|88)}" "${V#*(35|88)}"    # Why 35 is not left out?
35xA 35xA
$ echo "${V##?(35|88)}" "${V##*(35|88)}"  # Why is it omitted when ## is used?
xA xA

匹配后缀模式 中使用 ?()*()(使用 %%%):

$ echo "${V%5?(xA|Bz)}"                   # 5xA is omitted
3
$ echo "${V%?(xA|Bz)}" "${V%*(xA|Bz)}"    # why xA is not left out?
35xA 35xA
$ echo "${V%%?(xA|Bz)}" "${V%%*(xA|Bz)}"  # xA is omitted when %% is used
35 35

我在 bash 版本 3.2.25、4.1.2 和 4.1.6 中测试了这个问题,这让我觉得,也许我没有正确理解实际的底层 shell匹配模式的机制。

有人可以解释一下吗?

提前致谢

如果您使用 @ 而不是 ? 那么它会按预期工作:

$> echo "${V#@(35|88)}"
xAB

$> echo "${V%@(xAB|Bzh)}"
35

+ 而不是 * 的类似行为:

$> echo "${V#*(35|88)}"
35xAB

$>echo "${V#+(35|88)}"
xAB

是因为:

  • ?(pattern-list) # 匹配 零个 或给定模式的一次出现
  • @(pattern-list) # 匹配一个给定模式

并且:

  • *(pattern-list) # 匹配 零次 次或多次出现的给定模式
  • +(pattern-list) # 匹配一次次或多次出现的给定模式