Skip to main content
Shell globbing lets you match filenames using patterns. While * matches any string and ? matches a single character, square brackets ([ ]) define character classes, enabling you to match one character from a specific set or range.

Matching a Range of Characters

Given a directory:
$ ls
fileA fileB fileC fileD fileE
You can match only fileA, fileB, and fileC by specifying a range inside brackets:
$ ls file[A-C]
fileA fileB fileC
Here, [A-C] matches any uppercase letter from A through C. Note that the dash (-) defines a range and must go from lower to higher:
$ ls file[C-A]
ls: cannot access 'file[C-A]': No such file or directory

Common Examples

PatternMatchesDescription
file[A-C]fileA, fileB, fileCUppercase A–C
file[a-c]filea, fileb, filecLowercase a–c
file[1-3]file1, file2, file3Numeric 1–3
file[ACE]fileA, fileC, fileESpecific letters A, C, E

Negated Character Classes

Prefix ! or ^ inside brackets to exclude characters or ranges:
$ ls
fileA fileB fileC fileD fileE

$ ls file[^A-C]
fileD fileE

$ ls file[!A-C]
fileD fileE
In Bash both ! and ^ work for negation. POSIX shells require ! at the start of the class.
The image explains that square brackets are special characters in Shell used for creating glob expressions by matching characters inside the brackets.

Listing Specific Characters

To match non-consecutive filenames such as fileA, fileC, and fileE, simply list them:
$ ls file[ACE]
fileA fileC fileE

Case Sensitivity

Globbing in Bash is case sensitive. If you have both uppercase and lowercase files:
$ touch filea fileb filec filed filee
$ ls
fileA fileB fileC fileD fileE filea fileb filec filed filee
To match only lowercase:
$ ls file[a-c]
filea fileb filec
To remove both lowercase and uppercase a–e, combine ranges:
$ rm file[a-eA-E]
$ ls
fileD fileE
When mixing ranges, list them in the order you want matched: here a-e before A-E.

Numeric Ranges and Negation

Numeric ranges behave the same way:
$ touch file1 file2 file3 file4 file5
$ ls file[1-3]
file1 file2 file3

$ ls file[4-5]
file4 file5

$ ls file[^1-3]
file4 file5

$ ls file[!1-3]
file4 file5

Multiple Character Classes

You can chain classes to match multiple positions. For example, to match filea1, filea2, fileb1, fileb2:
$ touch filea1 filea2 filea3 fileb1 fileb2 fileb3

$ ls file[a-b][1-2]
filea1 filea2 fileb1 fileb2
Each [a-b] matches one letter, and [1-2] matches one digit. If you try only [1-2], it won’t match because the letter is missing:
$ ls file[1-2]
ls: cannot access 'file[1-2]': No such file or directory

Literal Characters Inside Brackets

Inside character classes, special glob characters lose their meaning:
$ ls file[a][*]
ls: cannot access 'file[a][*]': No such file or directory
To use * as a wildcard, place it outside the brackets:
$ ls filea*
filea1 filea2 filea3
Or constrain both positions:
$ ls file[a][1-3]
filea1 filea2 filea3

Globbing vs. File Creation

Globs match existing filenames; they do not generate names. If you use a glob in a command like touch when no files match, the pattern is taken literally:
$ touch ?ail
$ ls
'?ail'
To produce a series of filenames based on a pattern, consider using brace expansion instead of globs.
Globbing won’t create files—only match them. If you expect new files, use brace expansion or a loop.