Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this pattern match `ab`, but not `ba`?

I fiddled around with extended globbing in bash, but there is some oddity with the inverse matcher !(PATTERN). Consider the following example

$ touch ab ba
$ shopt -s extglob

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

Now it looks like !() matches the empty string, but why doesn't *a*!(a) match ba?

I assumed that in the second example ab is matched like so

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

which in turn would suggest a match of ba in the third case like so

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

but looks like this doesn't work.

Even considering greediness, that doesn't make any sense to me. What am I missing?

edit:
I'm on GNU bash, Version 4.1.7(2)-release (i386-apple-darwin10.4.0)

like image 452
user123444555621 Avatar asked Sep 26 '12 07:09

user123444555621


1 Answers

This is indeed odd. I could reproduce your behavior. The strangeness is the * behind the a character. When I execute your code:

$ echo *a*!(a)
ab

... it is as you described. But if I skip that second * it matches both files

$ echo *a!(a)
ab ba

Which means that your matching elements should be correct. The question is, why does this second asterisk not match the null string in the first example. As the documentation says it should match the null string, but it seems as if this is not working properly.

Maybe our bash versions do not match the documentation?

$ bash --version
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin11)
Copyright (C) 2007 Free Software Foundation, Inc.
like image 52
mana Avatar answered Oct 22 '22 05:10

mana