The Problem
You need to delete 50 log files. Do you run rm 50 times? Move 100 images—one by one?
Wildcards solve this. They let you match multiple files with a single pattern.
What Are Wildcards?
Wildcards are special characters that represent patterns in filenames.
The three main wildcards:
-
*- Matches zero or more characters -
?- Matches exactly one character -
[]- Matches a range of characters
The Asterisk (*): Match Everything
The * matches zero or more characters.
Basic Usage
# List all files starting with "abc"
ls abc*
# Matches: abc, abc123, abc-file.txt, abcdefg
# Delete all .tmp files
rm *.tmp
# Matches: data.tmp, backup.tmp, cache.tmp
# Find files containing "xy"
rm *xy*
# Matches: xyfile, file-xy-data, xy, data-xy.txt
Real-World: Cleaning Log Files
You have hundreds of logs in /var/log/app/:
app-2024-11-01.log
app-2024-11-02.log
...
app-2024-11-30.log
Delete all November logs:
rm /var/log/app/app-2024-11-*.log
Compress before archiving:
gzip /var/log/app/app-2024-11-*.log
The Question Mark (?): Match One Character
The ? matches exactly one character—no more, no less.
Basic Usage
# Match files with one char before "abc-xyz"
ls ?abc-xyz*
# Matches: 1abc-xyz, 2abc-xyz, xabc-xyz
# NOT: abc-xyz, 10abc-xyz
# Match single-character files
ls ?
# Matches: a, 1, x
# NOT: ab, 123
# Match specific patterns
ls file-?.txt
# Matches: file-1.txt, file-a.txt
# NOT: file-10.txt, file.txt
Real-World: Finding Backup Versions
Your backups:
backup-1.tar.gz
backup-2.tar.gz
...
backup-9.tar.gz
backup-10.tar.gz
List only single-digit backups:
ls backup-?.tar.gz
# Shows: backup-1.tar.gz through backup-9.tar.gz
# Excludes: backup-10.tar.gz
Square Brackets ([]): Match Ranges
The [] matches any single character within the brackets.
Basic Usage
# Match files starting with "c" or "d"
ls -l [cd]*
# Matches: cat.txt, dog.log, config.yml
# NOT: apple.txt, bat.sh
# Match files starting with any digit
ls [0-9]*
# Matches: 1file.txt, 2data.log, 9report.pdf
# NOT: file1.txt (doesn't start with digit)
# Match specific characters
ls file[123].txt
# Matches: file1.txt, file2.txt, file3.txt
# NOT: file4.txt
# Match letter ranges
ls [a-f]*
# Matches files starting with: a, b, c, d, e, f
Real-World: Organizing Project Files
Your project structure:
config-dev.yml
config-prod.yml
config-test.yml
data-dev.csv
data-prod.csv
data-test.csv
List only dev and test files (not production):
ls *-[dt]*
# Matches: config-dev.yml, config-test.yml, data-dev.csv, data-test.csv
# Excludes: config-prod.yml, data-prod.csv
Brace Expansion ({}): Create Multiple Files
Not a wildcard, but incredibly useful.
Basic Usage
# Create 9 files
touch abc{1..9}-xyz
# Creates: abc1-xyz, abc2-xyz, ..., abc9-xyz
# Create files with different extensions
touch file.{txt,log,bak}
# Creates: file.txt, file.log, file.bak
# Create numbered directories
mkdir project-{001..010}
# Creates: project-001, project-002, ..., project-010
Real-World: Test Environment Setup
# Create 100 test CSV files
touch test-data-{001..100}.csv
# Create directory structure
mkdir -p {dev,test,prod}/{logs,config,data}
# Creates: dev/logs, dev/config, dev/data, test/logs, etc.
Special Characters
Backslash (): Escape Characters
Match files with wildcard characters in their names:
# Match file literally named "file*.txt"
ls file\*.txt
# Matches: file*.txt (actual filename with asterisk)
# Match files with spaces
ls my\ file.txt
# Or use quotes
ls "my file.txt"
Dollar Sign ($): Variables
Reference variables:
# Use variable in command
USER_DIR=/home/ubuntu
ls $USER_DIR/*.txt
# Expands to: ls /home/ubuntu/*.txt
# Current user's home
ls $HOME/documents
# Same as: ls ~/documents
Using man for Documentation
Every command has a manual:
man ls
# Shows complete documentation
Navigate man pages:
-
Space- Scroll down -
b- Scroll up -
/- Search -
q- Quit
Quick help:
ls --help
# Brief usage summary
Combining Wildcards
Wildcards are powerful when combined:
# Match all .log files from November or December
ls app-2024-1[12]-*.log
# Matches: app-2024-11-01.log, app-2024-12-15.log
# Delete temp files with single-char extensions
rm temp-*.?
# Matches: temp-data.1, temp-file.x
# NOT: temp-data.txt (3 chars)
# Copy specific backup files
cp backup-[1-5]?.tar.gz /archive/
# Matches: backup-10.tar.gz through backup-59.tar.gz
Common Mistakes
❌ Mistake #1: Not quoting wildcards with find
# Wrong - shell expands * before find sees it
find . -name *.txt
# Right - quote to pass literal * to find
find . -name "*.txt"
❌ Mistake #2: Using * when you need ?
# Too broad
ls file-*.txt
# Matches: file-1.txt, file-10.txt, file-abc.txt
# More specific
ls file-?.txt
# Matches only: file-1.txt, file-a.txt
❌ Mistake #3: Not testing before deleting
# DANGEROUS - always check first
ls *.tmp # Verify what will be deleted
rm *.tmp # Then delete
# Or use -i flag for confirmation
rm -i *.tmp
Practical Examples
Clean build artifacts
# Remove compiled files
rm *.o *.class *.pyc
# Remove all files in current directory
rm ./*
Find and process files
# Count lines in all Python files
wc -l *.py
# Search in all config files
grep "database" *.conf
# Copy all images to backup
cp *.{jpg,png,gif} /backup/images/
Batch rename
# Rename .txt to .bak
for file in *.txt; do
mv "$file" "${file%.txt}.bak"
done
Quick Reference
| Wildcard | Matches | Example | Result |
|---|---|---|---|
* |
Zero or more chars | abc* |
abc, abc1, abc-file |
? |
Exactly one char | ?abc |
1abc, xabc |
[] |
Char in brackets | [abc]* |
apple, bat, cat |
[a-z] |
Range | [a-z]* |
lowercase start |
[0-9] |
Digits | file[0-9].txt |
file0.txt-file9.txt |
{} |
Brace expansion | {1..5} |
1 2 3 4 5 |
Advanced Patterns
Exclude patterns
# List all files except .txt
ls !(*.txt)
# Requires: shopt -s extglob
Multiple wildcards
# Match complex patterns
ls [a-z]*[0-9].{log,txt}
# Matches: app1.log, data5.txt, test9.log
Case-insensitive matching
# Enable case-insensitive globbing
shopt -s nocaseglob
ls *.TXT # Also matches .txt, .Txt, .TxT
Performance Tips
Be specific
# Slower - searches everywhere
ls *file*
# Faster - more specific pattern
ls file-*.log
Use quotes when needed
# Shell expands first (can be slow with many files)
echo *
# Faster for large directories
echo "*"
Key Takeaways
-
*matches zero or more - Broadest pattern -
?matches exactly one - Precise matching -
[]matches ranges - Specific character sets -
{}creates multiple items - File creation tool -
Test with
lsbeforerm- Always verify - Quote when needed - Prevent unwanted expansion
-
Read
manpages - Detailed documentation
Wildcards turn repetitive operations into single commands. Master these and you'll work exponentially faster.
What's your most useful wildcard pattern? Share in the comments!
Follow for more practical Linux tips as I document my journey into cloud engineering and DevOps.
Top comments (0)