13. Filename Expansion
Filename expansion allwos the selection of paths by simple patterns. Words containing one of the characters "*", "?", "[" are treated as pattern and replaced by file- or directory names matching this pattern. The "*" matches any characters, except a leading ".":
$ ls *
0file Afile _file abcfile bfile f le fiiile fiile file fjjle fjle fle
The leading "." must match explicitly::
$ ls .*
.file
So the actual directory with alias "." and the parent directory with alias ".." are excluded from the matches. Otherwise, unwanted recursion and system damage may occur. If no filename can be matched the literal value string is taken:
$ echo g*rl
g*rl
The "?" matches any single character, except ".":
$ ls ?file
0file Afile _file bfile
Sets of characters can be matched:
$ ls [Ab]file
Afile bfile
as well as character ranges:
$ ls [a-zA-Z]file
Afile bfile
The range depends on the collation locale, stored by the LC_COLLATE variable. Some character ranges are predefined. They are called character classes, e.g. alnum, alpha, ascii, blank, cntrl, digit, graph, lower, print, punct, space, upper, word and xdigit:
$ ls [:alpha:]file
0file Afile bfile
To exclude character from a pattern the "[^...]" operator is used. The following expression excludes all filenames which start by 0, 1, 2,.., 9, "_", or "-":
$ ls [^0-9._-]*
Afile abcfile bfile f le fiiile fiile file fjjle fjle fle
When the option extglob is set, Bash allows even the quantification of patterns:
$ shopt -o extglob
To treat a pattern to be matched zero or one time the "?(...)" operator is used:
$ ls f?(i)le
fle file
or any time:
$ ls f*([ij])le
fiiile fiile file fjjle fjle fle
or at least one time:
$ ls f+(i)le
fiiile fiile file
Alternative patterns are separated by the "|" operator between the "?(...)", "*(...)" or "+(...)" operators:
$ ls -d /home/+(pa|user19)
/home/pa /home/user19
To allow only one match from the alternative patterns prefix the list by the "@" operator:
$ ls -d /home/@(pa|user19)
/home/pa /home/user19
To allow any match without the alternatives prefix the list by the "!" operator:
$ ls -d /home/!(mark|baracuda)
/home/pa /home/user19