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