I'm trying to understand how extended wilcards expansion works and I got into the following problem.
In my current directory ~/t, I have two files called chair and table. With the Bash shell, command ls *(a-z)* lists both of them, but ls *(a-z) doesn't. Why? I have enabled extended globbing with shopt -s extglob.
I guess ls *(a-z) fails to list both file because in this case the * would expand to 0+ characters, as in basic wildcards expansion, and then the (a-z) wouldn't expand to anything. If (a-z) doesn't expand to anything, Bash will try to match it literally. Since I have no file in my current directory that ends in (a-z), command ls fails in this case and lists nothing.
However, according to my previous reasoning, the expression *(a-z)* should match only a filename starting with any 0+ characters, followed by the literal "(a-z)", followed by 0+ characters. But that seems is not the case, becuase ls *(a-z)* does list my files chair and table.
~/t$ ls
chair table
~/t$ ls *(a-z)*
chair table
~/t/$ ls *(a-z)
ls: cannot access '*(a-z)': No such file or directory
You have the
extgloboption enabled, which is why neither glob is a syntax error in the first place.*(a-z)matches zero or more occurrences of the literal stringa-z, not one or more characters in the rangea-z. Since no files match that pattern, the string is passed literally tols, which doesn't find a file by that name.*(a-z)*matches the same substring, followed by an arbitrary set of characters, so essentially behaves like*alone. It expands tochairandtable, which are both passed as separate arguments tols.If you want to match files starting with 0 or more lowercase letters, use
*([a-z])*. Ordinary globs have no way to repeat a particular set of characters, only arbitrary characters. Extended globs are equivalent in power to regular expressions, with*([a-z])equivalent to the regular expression[a-z]*.Of course,
*([a-z])*doesn't really make sense, because it will match anything by simply matching 0 lowercase characters followed by anything. Something more sensible would be to match files starting with one or more lowercase characters, namely+([a-z])*.