|

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
PatternMatches
*.txtAny file with .txt extension
?a?.txt3-char name, second char a, .txt
[abc]*Starts with a, b, or c
file{1,2,3}.txtfile1.txt, file2.txt, file3.txt
file{1,2}.txtfile1.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].txtEnds 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. ls never sees the * โ€” it sees the expanded list.


Wildcard Characters

WildcardMeaningExampleMatches
*Any number of characters (0 or more)*.txtfile.txt, a.txt, .txt
?Exactly one character?a?.txtcat.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 commasfile{1,2}.txtfile1.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.

ClassMatchesExample
[: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

WildcardMeaningExample
*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 expansionfile{1,2}.txt

Character Classes

ClassMatches
[[:alnum:]]Letters + digits
[[:alpha:]]Letters
[[:digit:]]Digits
[[:lower:]]Lowercase
[[:upper:]]Uppercase
[[:blank:]]Space, tab
[[:punct:]]Punctuation
[[:xdigit:]]Hex digits

Common Patterns

PatternMatches
*.txtAll .txt files
file*Files starting with file
*fileFiles ending with file
?.txtSingle-char .txt files
??.txtTwo-char .txt files
[abc]*Starting with a, b, or c
[!0-9]*Not starting with digit
file{1,2,3}.txtfile1, file2, file3
*[23].txtEnding 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

PitfallProblemSolution
rm * without checkingDeletes everythingls * first
Expecting ? to match manyOnly matches oneUse * for many
Case sensitivity*.TXT โ‰  *.txtWatch case
Empty expansionPattern matches nothingShell passes pattern literally
Quoting too much"*.txt" won’t expandQuote only when needed
Forgetting [!...]Uses [^...] (regex)Use ! for glob negation

When to Quote Wildcards

SituationUseExample
Want expansionNo quotesls *.txt
Want literal characterSingle quotesecho '*.txt'
Want variable expansionDouble quotesecho "$dir"/*.txt
Pass to findQuote or escapefind . -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

WildcardMeaningExample
*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 expansionfile{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 echo or ls before 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!