Linux CLI 5 ๐ง Wildcards
Wildcards are special characters that allow us to select filenames based on character patterns. They’re also called glob patterns โ and they’re one of the most powerful features of the command line.
A Quick Look at the Examples
ls *.txt
ls ?a?.txt
ls [abc]*
ls file{1,2,3}.txt
ls file{1,2}.txt
ls [[:alnum:]]*
ls [![:alpha:]]*
ls *[[:lower:]2]
ls *[23].txt
| Pattern | Matches |
|---|---|
*.txt | Any file with .txt extension |
?a?.txt | 3-char name, second char a, .txt |
[abc]* | Starts with a, b, or c |
file{1,2,3}.txt | file1.txt, file2.txt, file3.txt |
file{1,2}.txt | file1.txt, file2.txt |
[[:alnum:]]* | Starts with any alphanumeric character |
[![:alpha:]]* | Does not start with a letter |
*[[:lower:]2] | Ends with lowercase letter or 2 |
*[23].txt | Ends with 2 or 3 before .txt |
What Are Wildcards?
Wildcards are special characters used by the shell to match filenames based on patterns.
Key points:
- Also called glob patterns
- The shell expands them before the command runs
- Used with commands like
ls,cp,mv,rm,find - Case-sensitive by default
How it works:
ls *.txt
โ
โผ
Shell expands to: ls file1.txt file2.txt notes.txt
โ
โผ
ls receives the list of files
Important: The shell, not the command, does the matching.
lsnever sees the*โ it sees the expanded list.
Wildcard Characters
| Wildcard | Meaning | Example | Matches |
|---|---|---|---|
* | Any number of characters (0 or more) | *.txt | file.txt, a.txt, .txt |
? | Exactly one character | ?a?.txt | cat.txt, bat.txt |
[chars] | Any one character in the set | [abc]* | apple, banana, cherry |
[!chars] | Any one character NOT in the set | [!abc]* | dog, fish, zebra |
{p1,p2} | Any of the patterns separated by commas | file{1,2}.txt | file1.txt, file2.txt |
[a-z] | Any character in the range | [a-c]* | apple, banana, cherry |
[[:class:]] | Any character from a character class | [[:digit:]]* | Files starting with a digit |
Basic Wildcards โ Detailed
* โ Match Any Number of Characters
ls *.txt # All files ending in .txt
ls file* # All files starting with "file"
ls * # All files in current directory
ls a*b # Files starting with "a" and ending with "b"
Examples:
$ ls
file.txt file2.txt notes.txt script.sh image.png
$ ls *.txt
file.txt file2.txt notes.txt
$ ls file*
file.txt file2.txt
$ ls *
file.txt file2.txt notes.txt script.sh image.png
? โ Match Exactly One Character
ls ?.txt # Single-char files with .txt
ls ?a?.txt # 3-char names with "a" in middle
ls file?.txt # file1.txt, fileA.txt โ but NOT file10.txt
Examples:
$ ls
a.txt b.txt ab.txt abc.txt file1.txt file10.txt
$ ls ?.txt
a.txt b.txt
$ ls ??*.txt
ab.txt abc.txt
$ ls file?.txt
file1.txt
# NOT file10.txt โ ? matches exactly ONE character
[chars] โ Match Any One Character in the Set
ls [abc]* # Starts with a, b, or c
ls file[123].txt # file1.txt, file2.txt, file3.txt
ls [a-z]* # Starts with lowercase letter
ls [A-Z]* # Starts with uppercase letter
ls [0-9]* # Starts with digit
Examples:
$ ls
apple.txt banana.txt cherry.txt dog.txt zebra.txt
$ ls [abc]*
apple.txt banana.txt cherry.txt
$ ls [a-c]*
apple.txt banana.txt cherry.txt
# Range: a through c
$ ls [ab]*
apple.txt banana.txt
[!chars] โ Match Any Character NOT in the Set
ls [!abc]* # Does NOT start with a, b, or c
ls [!0-9]* # Does NOT start with a digit
ls file[!1].txt # fileX.txt but not file1.txt
Examples:
$ ls
apple.txt banana.txt cherry.txt dog.txt zebra.txt
$ ls [!abc]*
dog.txt zebra.txt
# Excludes apple, banana, cherry
$ ls [!a-c]*
dog.txt zebra.txt
{p1,p2} โ Brace Expansion (Match Multiple Patterns)
ls file{1,2,3}.txt # file1.txt file2.txt file3.txt
ls file{1,2}.txt # file1.txt file2.txt
ls {a,b,c}.txt # a.txt b.txt c.txt
ls file{1,2}.{txt,md} # file1.txt file1.md file2.txt file2.md
Note: Brace expansion is a shell feature, not a glob. It generates multiple patterns before globbing.
Examples:
$ ls
file1.txt file2.txt file3.txt file4.txt
$ ls file{1,2,3}.txt
file1.txt file2.txt file3.txt
$ ls file{1,2}.txt
file1.txt file2.txt
$ echo file{1,2}.{txt,md}
file1.txt file1.md file2.txt file2.md
Character Classes
Character classes use the syntax [[:class:]] โ they match any character from a predefined category.
| Class | Matches | Example |
|---|---|---|
[:alnum:] | Alphanumeric (letters + digits) | [[:alnum:]]* |
[:alpha:] | Letters (a-z, A-Z) | [[:alpha:]]* |
[:digit:] | Digits (0-9) | [[:digit:]]* |
[:lower:] | Lowercase letters (a-z) | [[:lower:]]* |
[:upper:] | Uppercase letters (A-Z) | [[:upper:]]* |
[:blank:] | Space and tab | โ |
[:space:] | Whitespace (space, tab, newline) | โ |
[:punct:] | Punctuation | [[:punct:]]* |
[:xdigit:] | Hexadecimal digits (0-9, a-f, A-F) | [[:xdigit:]]* |
[:cntrl:] | Control characters | โ |
[:graph:] | Printable characters (except space) | โ |
[:print:] | Printable characters (including space) | โ |
Character Class Examples
ls [[:alnum:]]* # Starts with a letter OR digit
ls [[:alpha:]]* # Starts with a letter
ls [[:digit:]]* # Starts with a digit
ls [[:upper:]]* # Starts with an uppercase letter
ls [[:lower:]]* # Starts with a lowercase letter
Examples:
$ ls
apple.txt Apple.txt 123file.txt _file.txt z.txt Z.txt
$ ls [[:lower:]]*
apple.txt z.txt
# Lowercase only
$ ls [[:upper:]]*
Apple.txt Z.txt
# Uppercase only
$ ls [[:digit:]]*
123file.txt
# Digits only
$ ls [[:alpha:]]*
apple.txt Apple.txt z.txt Z.txt
# Letters only
$ ls [[:alnum:]]*
apple.txt Apple.txt 123file.txt z.txt Z.txt
# Letters and digits
$ ls [![:alpha:]]*
123file.txt _file.txt
# NOT starting with a letter
Combining Wildcards
You can combine wildcards for complex patterns:
ls *[23].txt # Ends with 2 or 3 before .txt
ls *[[:lower:]2] # Ends with lowercase letter or 2
ls file[0-9][0-9].txt # file followed by two digits
ls [!a-z]* # Does NOT start with lowercase
ls *.{txt,md,sh} # Multiple extensions
Examples:
$ ls
file1.txt file2.txt file3.txt file22.txt file33.txt
notes.md script.sh README.md
$ ls *[23].txt
file2.txt file3.txt file22.txt file33.txt
$ ls *[!0-9].txt
# Files whose name (before .txt) ends with a non-digit
file1.txt file2.txt file3.txt
$ ls *.{txt,md}
file1.txt file2.txt file3.txt file22.txt file33.txt
notes.md README.md
$ ls file[0-9][0-9].txt
file22.txt file33.txt
# Two digits after "file"
Complete Example Session
Let’s build a directory and test all patterns:
# 1. Create test files
$ touch file1.txt file2.txt file3.txt file10.txt file22.txt
$ touch apple.txt banana.txt cherry.txt
$ touch notes.md readme.md
$ touch script.sh
$ touch 123file.txt _underscore.txt
$ touch UPPER.txt lower.txt
# 2. List everything
$ ls
123file.txt UPPER.txt _underscore.txt apple.txt banana.txt
cherry.txt file1.txt file2.txt file3.txt file10.txt
file22.txt lower.txt notes.md readme.md script.sh
# 3. Match by extension
$ ls *.txt
123file.txt UPPER.txt _underscore.txt apple.txt banana.txt
cherry.txt file1.txt file2.txt file3.txt file10.txt
file22.txt lower.txt
# 4. Match by prefix
$ ls file*
file1.txt file2.txt file3.txt file10.txt file22.txt
# 5. Match by single character
$ ls ?.txt
# Single-char files: (none)
$ ls ??*.txt
# 2+ char files: all .txt files
# 6. Match by character set
$ ls [abc]*
apple.txt banana.txt cherry.txt
# 7. Brace expansion
$ ls file{1,2,3}.txt
file1.txt file2.txt file3.txt
# 8. Character classes
$ ls [[:digit:]]*
123file.txt
$ ls [[:upper:]]*
UPPER.txt
$ ls [![:alpha:]]*
123file.txt _underscore.txt
# 9. Complex patterns
$ ls *[23].txt
file2.txt file3.txt file22.txt
$ ls file[0-9][0-9].txt
file10.txt file22.txt
# 10. Multiple extensions
$ ls *.{txt,md}
# All .txt and .md files
Quick Reference
Wildcard Characters
| Wildcard | Meaning | Example |
|---|---|---|
* | Any number of characters | *.txt |
? | Exactly one character | ?.txt |
[abc] | Any one of a, b, c | [abc]* |
[a-z] | Any in range | [a-z]* |
[!abc] | Not a, b, or c | [!abc]* |
{a,b} | Brace expansion | file{1,2}.txt |
Character Classes
| Class | Matches |
|---|---|
[[:alnum:]] | Letters + digits |
[[:alpha:]] | Letters |
[[:digit:]] | Digits |
[[:lower:]] | Lowercase |
[[:upper:]] | Uppercase |
[[:blank:]] | Space, tab |
[[:punct:]] | Punctuation |
[[:xdigit:]] | Hex digits |
Common Patterns
| Pattern | Matches |
|---|---|
*.txt | All .txt files |
file* | Files starting with file |
*file | Files ending with file |
?.txt | Single-char .txt files |
??.txt | Two-char .txt files |
[abc]* | Starting with a, b, or c |
[!0-9]* | Not starting with digit |
file{1,2,3}.txt | file1, file2, file3 |
*[23].txt | Ending in 2 or 3 |
*.[ch] | .c or .h files |
Best Practices
โ Do This:
# Test patterns with echo first (safe!)
echo *.txt # Shows what would be matched
echo file{1,2,3}.txt
# Use ls to verify before destructive operations
ls *.log # Check first
rm *.log # Then delete
# Quote patterns when you want literal characters
echo "*" # Prints *
echo * # Expands to filenames
# Use character classes for portability
ls [[:digit:]]* # More portable than [0-9]*
# Combine for precise matching
ls file[0-9][0-9].txt # file + 2 digits
โ Don’t Do This:
# Don't use rm * without checking!
rm * # โ Deletes EVERYTHING
ls * # โ
Check first
# Don't forget * matches zero characters
ls *.txt # Also matches ".txt" (if it exists)
# Don't confuse globs with regex
# Globs are for filenames; regex is for text matching
# [!abc] in glob โ [^abc] in regex
# Don't use braces for filenames that don't exist
ls file{1,2,3,4,5,6,7,8,9,10}.txt # Fails if any don't exist
# Don't forget case sensitivity
ls *.TXT # Different from *.txt on Linux
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
rm * without checking | Deletes everything | ls * first |
Expecting ? to match many | Only matches one | Use * for many |
| Case sensitivity | *.TXT โ *.txt | Watch case |
| Empty expansion | Pattern matches nothing | Shell passes pattern literally |
| Quoting too much | "*.txt" won’t expand | Quote only when needed |
Forgetting [!...] | Uses [^...] (regex) | Use ! for glob negation |
When to Quote Wildcards
| Situation | Use | Example |
|---|---|---|
| Want expansion | No quotes | ls *.txt |
| Want literal character | Single quotes | echo '*.txt' |
| Want variable expansion | Double quotes | echo "$dir"/*.txt |
Pass to find | Quote or escape | find . -name "*.txt" |
Examples:
$ touch a.txt b.txt
$ ls *.txt
a.txt b.txt
$ echo "*.txt"
*.txt # Literal โ no expansion
$ echo '*.txt'
*.txt # Literal โ no expansion
$ echo *.txt
a.txt b.txt # Expanded by shell
Practical Examples
1. Backup all .conf files
cp /etc/*.conf ~/backup/
2. Delete all temporary files
rm *.tmp
rm *.bak
3. List images by format
ls *.{jpg,png,gif}
4. Find files with 2-digit numbers
ls file[0-9][0-9].txt
5. Rename with brace expansion
mv image.{jpg,jpeg}
# Renames image.jpg โ image.jpeg
6. Match multiple extensions
ls *.{c,h}
# All C source and header files
7. Exclude hidden files (which start with .)
ls [!.]*
# Files NOT starting with a dot
Summary
| Wildcard | Meaning | Example |
|---|---|---|
* | Any characters (0+) | *.txt |
? | One character | ?.txt |
[abc] | One of a, b, c | [abc]* |
[a-z] | Range | [a-z]* |
[!abc] | Not a, b, c | [!abc]* |
{1,2} | Brace expansion | file{1,2}.txt |
[[:class:]] | Character class | [[:digit:]]* |
Key takeaways:
*is the most common wildcard โ matches any number of characters?matches exactly one character[...]matches one character from a set or range{...}expands to multiple patterns (brace expansion)[[:class:]]matches by character category!inside[ ]means “not” (e.g.,[!abc])- Test with
echoorlsbefore running destructive commands - The shell expands wildcards before the command runs
Remember: Wildcards are one of the most powerful features of the command line. They save you from typing long filenames and let you operate on many files at once. But with great power comes great responsibility โ always test with ls first before using rm with wildcards!
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!