Bash Wildcards
Wildcards are special symbols that stand for unknown characters in file names. One short pattern can select hundreds of files. The process is called globbing, and Bash expands the pattern into a list of matching names before the command runs.
The Playing Card Analogy
Imagine asking a dealer for "any card with a heart". The dealer hands over every heart card. A wildcard works as that request, and the folder acts as the deck.
Folder: a.txt b.txt notes.txt photo.jpg report.pdf ls *.txt ---> a.txt b.txt notes.txt ls ?.txt ---> a.txt b.txt ls *.jp* ---> photo.jpg
The Main Wildcards
| Symbol | Meaning | Example |
|---|---|---|
| * | Any number of characters, including none | *.txt |
| ? | Exactly one character | file?.txt |
| [abc] | One character from the set | file[123].txt |
| [a-z] | One character from a range | [a-c]*.sh |
| [!abc] | One character outside the set | [!a]*.txt |
| {a,b} | Brace expansion with a list of choices | file.{txt,md} |
Create Practice Files
mkdir wild
cd wild
touch file1.txt file2.txt file3.txt file10.txt
touch photo.jpg photo.png report.pdf notes.mdThe Star Wildcard
ls *.txt
ls photo.*
ls f*The first command lists all four text files. The second lists both photo files. The third lists every file that starts with the letter f.
The Question Mark Wildcard
ls file?.txtOutput:
file1.txt file2.txt file3.txtThe name file10.txt stays out because it holds two characters where the pattern allows one.
Character Sets and Ranges
ls file[12].txt # file1.txt file2.txt
ls file[1-3].txt # file1.txt file2.txt file3.txt
ls [!f]* # names that do not start with fBrace Expansion
Braces generate text. They do not search for existing files.
echo file.{txt,md,pdf}
mkdir -p project/{src,docs,tests}
touch day{1..5}.log
echo {a..e}Output of the first and last lines:
file.txt file.md file.pdf
a b c d eThe second command builds three folders at once, and the third creates five log files.
Hidden Files
The star skips files that begin with a dot. Match them with an explicit dot:
ls .*
ls -d .[!.]*Use Wildcards in Scripts
#!/bin/bash
for file in *.txt
do
echo "Processing $file"
doneA loop with a wildcard handles file names that contain spaces, as long as the variable stays inside quotation marks.
When nothing matches, Bash passes the pattern text itself to the command. Turn on the nullglob option to get an empty list instead:
shopt -s nullglobQuote to Stop Expansion
Quotation marks turn wildcards back into plain characters:
echo *.txt # expands to file names
echo "*.txt" # prints the star literallyExtended Patterns
Turn on extglob to use patterns such as !(pattern):
shopt -s extglob
ls !(*.txt) # everything except text files
ls *.@(jpg|png) # jpg or png filesPractical Example: Sort Files Into Folders
This script moves pictures and documents into separate folders:
#!/bin/bash
mkdir -p pictures documents
mv *.jpg *.png pictures/ 2>/dev/null
mv *.pdf *.txt documents/ 2>/dev/null
echo "Files sorted"The redirect 2>/dev/null hides error messages when a pattern matches nothing.
Wildcards Versus Regular Expressions
Wildcards and regular expressions look alike but follow different rules. In a wildcard, the star means "any text". In a regular expression, the star means "repeat the previous item". Tools such as grep use regular expressions, while the shell uses wildcards for file names.
Key Takeaways
*matches any text and?matches one character.[ ]matches one character from a set or range.- Braces create lists of names and numbers.
- Bash expands wildcards before the command starts.
- Quotation marks switch wildcard expansion off.
