Globbing and Wildcards
By the end of this lesson you'll be able to match many files at once with the shell's wildcards — * , ? , and bracket sets — generate names with brace expansion, recurse with ** , expand ~ to your home directory, and know exactly when to quote a pattern so the shell leaves it alone.
Learn Globbing and Wildcards in our free Command Line course — an interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Cli course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
1. Set Up a Predictable Sandbox
Globbing matches the files that actually exist, so to get the same output every time we first create a known set of files. Run this once; every later example assumes you're inside this globdemo folder.
2. The * Wildcard: Any Run of Characters
* matches any sequence of characters (including an empty one) within a single filename. Two rules trip people up: a bare * does not match files that begin with a dot (so .hidden is skipped), and * does not cross the / between directories — it stays inside one folder.
3. The ? Wildcard: Exactly One Character
? matches exactly one character — no more, no less. That's the difference between file?.txt (matches file1.txt ) and file??.txt (matches file10.txt ). Use one ? per character you want to leave flexible.
4. Bracket Sets [abc] and Ranges [a-z]
A bracket expression [...] matches exactly one character from the listed set. List choices explicitly with [12] , or give a range with a hyphen like [1-5] or [a-z] . As always, a glob only lists files that truly exist, so a range that matches nothing is passed through literally.
5. Negating a Set with [!...]
Put ! (or ^ ) as the first character inside the brackets to match a single character that is not in the set. So [!1] matches one character that isn't 1 , and [!0-9] matches one non-digit character. Both ! and ^ work in bash.
6. Brace Expansion {' '} and {' '} — Not Globbing!
Brace expansion is not globbing. The shell generates strings from the braces before any filename matching, so echo file{' '}.txt prints all three names whether or not the files exist . A real glob like file[1-3].txt only shows files that exist. They combine nicely: the shell expands the braces first, then matches the results as globs.
7. Globstar, Tilde, Quoting, and nullglob
Four power features. ** matches across subdirectories, but only after shopt -s globstar . ~ expands to your home directory (the value of $HOME ). Quoting or escaping a pattern ( "*.txt" or \*.txt ) disables globbing so the literal text is passed along. And by default a glob that matches nothing is left literal — shopt -s nullglob makes it expand to nothing instead.
Fill in the blank marked _ using the # 👉 hint so only the single-digit text files match (leaving out file10.txt ), then run it and check the Output panel matches.
Make echo print the literal pattern *.txt instead of expanding it, by quoting the argument. Fill in the blank, then run it.
No blanks this time — just a brief and an outline. Combine * , ? , bracket sets, brace expansion, and ** in the globdemo folder, and check your output against the hints in the comments.
Practice quiz
In bash, what does the * wildcard match by default?
- Any run of characters in a filename, but NOT files that start with a dot
- Exactly one character
- Only files that start with a dot
- Any text including the / between directories
Answer: Any run of characters in a filename, but NOT files that start with a dot. A bare * matches any sequence of characters (including none) in one filename, but dotfiles are skipped unless you write the leading dot yourself or set dotglob.
Which wildcard matches exactly ONE character?
- *
- +
- ?
- .
Answer: ?. ? matches any single character. file?.txt matches file1.txt but not file12.txt.
What does the pattern [a-c]*.txt match?
- Any .txt file
- Files whose name starts with a, b, or c and ends in .txt
- Files named literally a-c.txt
- Only file named abc.txt
Answer: Files whose name starts with a, b, or c and ends in .txt. [a-c] is a character range that matches one character a, b, or c, so the pattern matches names beginning with a, b, or c that end in .txt.
How do you write a bracket expression that matches any single character EXCEPT a digit?
A ! (or ^) as the first character inside the brackets negates the set, so [!0-9] matches one character that is not a digit.
Which statement about brace expansion like {a,b,c} is TRUE?
- It only works if files matching each item exist
- It matches exactly one character like ?
- It is identical to a regex alternation and reads files
- It is NOT globbing; it generates the strings even when no matching file exists
Answer: It is NOT globbing; it generates the strings even when no matching file exists. Brace expansion is pure text generation done before globbing. echo a{1,2,3} prints a1 a2 a3 whether or not those files exist.
What does the numeric brace expansion {1..5} produce?
- 1 2 3 4 5
- Only 1 and 5
- An error in bash
- The single string 1..5
Answer: 1 2 3 4 5. Numeric sequence brace expansion {1..5} expands to 1 2 3 4 5.
What must you do before the ** globstar will match across directory levels in bash?
- Quote the pattern
- Enable it with shopt -s globstar
- Run set -e first
- Nothing, ** always recurses by default
Answer: Enable it with shopt -s globstar. In bash ** behaves like * unless you enable the globstar option with shopt -s globstar, which lets ** match files and directories recursively.
What does the tilde ~ expand to on its own?
- The current directory
- The root directory /
- A single character
- Your home directory, the value of HOME
Answer: Your home directory, the value of HOME. Tilde expansion turns a leading ~ into the path stored in HOME, so ~/notes becomes /home/you/notes.
How can you stop the shell from expanding a glob so a program receives the literal pattern *.txt?
- Use a capital STAR
- It is impossible to disable globbing
- Quote or escape it, for example "*.txt" or \*.txt
- Put a space after the star
Answer: Quote or escape it, for example "*.txt" or \*.txt. Globbing happens on unquoted words. Quoting ("*.txt") or escaping (\*.txt) passes the literal pattern through unchanged.
By default in bash, what happens when a glob like *.md matches no files?
- The command is skipped silently
- The pattern is passed through literally as the text *.md
- The shell prints an error and stops
- It expands to an empty string
Answer: The pattern is passed through literally as the text *.md. By default bash passes the unmatched pattern through literally as text; enabling shopt -s nullglob makes a non-matching glob expand to nothing instead.