为什么这种模式匹配`ab`,而不是'ba`?

时间:2012-09-26 07:15:02

标签: bash pattern-matching

我在bash中用extended globbing摆弄,但是反向匹配器!(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)

3 个答案:

答案 0 :(得分: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.

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

这是bug in Bash

  

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