8

我在 bash 中摆弄了扩展的 globbing,但是 inverse matcher 有一些奇怪的地方!(PATTERN)。考虑以下示例

$ touch ab ba
$ shopt -s extglob

$ echo *a*
ab ba
$ echo !(a)*a*
ab ba
$ echo *a*!(a)
ab

现在它看起来像!()匹配空字符串,但为什么不*a*!(a)匹配ba

我假设在第二个例子ab中是这样匹配的

!(a) ->  ""
*    ->  ""
a    ->  "a"
*    ->  "b"

这反过来会建议ba在第三种情况下匹配

*    ->  "b"
a    ->  "a"
*    ->  ""
!(a) ->  ""

但看起来这不起作用。

即使考虑到贪婪,这对我来说也没有任何意义。我错过了什么?

编辑:
我在GNU bash, Version 4.1.7(2)-release (i386-apple-darwin10.4.0)

4

3 回答 3

1

这确实很奇怪。我可以重现你的行为。奇怪的是角色的*背后a。当我执行您的代码时:

$ echo *a*!(a)
ab

……和你描述的一样。但是如果我跳过那一秒*,它会匹配两个文件

$ echo *a!(a)
ab ba

这意味着您的匹配元素应该是正确的。问题是,为什么第二个星号与第一个示例中的空字符串不匹配。正如文档所说,它应该匹配空字符串,但似乎这不能正常工作。

也许我们的 bash 版本与文档不匹配?

$ bash --version
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin11)
Copyright (C) 2007 Free Software Foundation, Inc.
于 2012-09-26T07:50:22.023 回答
1

这有效:()添加以消除歧义

echo @(*a*)!(a)
echo !(a)@(*a*)

奇怪 : *a*!(a)c,匹配abcbac(这是正常行为)

于 2012-09-26T10:22:39.010 回答
0

这是Bash 中的一个错误

Chet Ramey 写了
[...] 并将在下一个版本中修复。

于 2012-09-29T09:23:37.467 回答