Advanced Bash Scripting

Globs

Square

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

Note

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

Note

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.

Warning

Globbing won’t create files—only match them. If you expect new files, use brace expansion or a loop.

Watch Video

Watch video content

Practice Lab

Practice lab

Previous
Mixed
Next
Brace