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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With