LINUX / WILDCARDS & GLOBBING

Wildcards & globbing

Patterns that let the shell match groups of filenames without having to type every name individually.

globbing

Match filenames using shell patterns.

Description

Globbing is the process where the shell expands a pattern such as *.txt into matching filenames before a command is executed.

This means commands such as rm *.tmp can operate on many files without requiring their names to be written individually.

Important

Globbing is performed by the shell, not by commands such as ls or rm. The command usually receives the expanded filenames as arguments.

Example

$ ls *.txt
notes.txt
todo.txt
readme.txt
*

Match zero or more characters.

Description

The asterisk matches any sequence of characters within a filename, including no characters at all.

Useful patterns

*.txt Match every filename ending in .txt.
log* Match filenames beginning with log.
*backup* Match filenames containing backup.
* Match ordinary visible filenames in the current directory.

Example

$ ls *.jpg
photo.jpg
holiday.jpg
portrait.jpg

$ rm *.tmp
?

Match exactly one character.

Description

The question mark matches exactly one character in a filename.

Unlike *, it cannot match zero characters.

Useful patterns

file?.txt Match file1.txt and fileA.txt, but not file10.txt.
?.jpg Match filenames containing exactly one character before .jpg.
data??.csv Match exactly two characters after data.

Example

$ ls file?.txt
file1.txt
file2.txt
fileA.txt
[]

Match one character from a set or range.

Description

Square brackets match exactly one character from the characters listed inside them.

A range can be written with a hyphen, such as [0-9] or [a-z].

Useful patterns

file[123].txt Match file1.txt, file2.txt, or file3.txt.
file[0-9].txt Match a single digit from 0 through 9.
[a-z]* Match filenames beginning with a lowercase letter.
[abc]* Match filenames beginning with a, b, or c.

Example

$ ls image[0-9].png
image1.png
image2.png
image3.png
[!]

Match a character not in a set.

Description

When ! appears immediately after the opening bracket, it negates the character set.

The pattern matches one character that is not one of the characters listed.

Useful patterns

file[!0].txt Match one character that is not 0.
[!a-z]* Match filenames whose first character is not a lowercase letter.
[!0-9]* Match filenames that do not begin with a digit.

Note

Bash also accepts [^...] as a negated character class. For portable shell scripts, [!...] is the more traditional glob syntax.

{}

Generate multiple strings with brace expansion.

Description

Brace expansion is related to filename patterns but is technically different from globbing.

The shell expands the alternatives inside braces before pathname expansion takes place.

Useful patterns

{a,b,c} Generate three alternatives: a, b, and c.
file{1,2,3}.txt Generate file1.txt, file2.txt, and file3.txt.
{1..5} Generate the sequence from 1 through 5.

Example

$ mkdir project_{dev,test,prod}

$ ls
project_dev
project_prod
project_test

$ touch file{1..3}.txt

$ ls
file1.txt
file2.txt
file3.txt
**

Match files recursively through directories.

Description

Bash can use ** for recursive globbing when the globstar shell option is enabled.

With globstar enabled, ** can match directories at multiple levels.

Enable it

$ shopt -s globstar

Example

$ ls **/*.txt
notes.txt
docs/readme.txt
docs/linux/commands.txt
archive/old/notes.txt

Important

** is not universally recursive in every shell. Its behavior depends on the shell and its configuration. The example above refers specifically to Bash with globstar enabled.

dotfiles

Understand why ordinary globs ignore hidden files.

Description

In typical Unix shells, filenames beginning with . are hidden. A pattern such as * does not normally match them.

Example

$ ls *
notes.txt
script.sh
documents

$ ls -a
.
..
.bashrc
.config
notes.txt
script.sh
documents

Matching dotfiles

A pattern beginning with a literal dot can match hidden files.

$ ls .*
.bashrc
.profile
.config

Caution

Be careful with broad patterns involving hidden files. Commands that modify or remove matched files can have much larger effects than expected.

examples

Combine patterns with everyday commands.

List files

$ ls *.txt
$ ls image?.png
$ ls [0-9]*.log

Copy files

$ cp *.jpg images/
$ cp report[0-9].pdf archive/

Move files

$ mv *.bak backup/
$ mv draft?.txt drafts/

Remove files

$ rm *.tmp
$ rm test[0-9].log

Combining patterns

Patterns can be combined to make more precise matches.

$ ls project-*.txt
$ ls image[0-9][0-9].png
$ ls backup-??-*.tar.gz
glob-vs-regex

Do not confuse shell globs with regular expressions.

The difference

Shell globs and regular expressions both describe patterns, but they use different syntax and are interpreted by different systems.

Common examples

*.txt Glob: any filename ending in .txt.
.* Glob: filenames beginning with a literal dot.
.*\.txt$ Regex: a pattern matching a dot, followed by any characters and ending in .txt.
^file[0-9]+$ Regex: file followed by one or more digits, with nothing else.

Remember

* in a shell glob means "any sequence of filename characters", while * in a regular expression means "zero or more repetitions of the preceding expression".