Sagar.BlogArticle
All posts
All posts
Linux

Wildcards & Globbing — Match Files Without Typing Every Name

Master *, ?, [...], and {} to select files by pattern. Wildcards multiply your power — one command works on dozens or thousands of files at once.

January 15, 20255 min read
LinuxShellProductivity

Wildcards (also called globbing) let you describe a pattern instead of a specific filename. The shell expands the pattern to match all existing files before running the command — so rm *.log removes every .log file without you naming each one.

Globing is a shell feature, not a command feature — it works with ls, cp, mv, rm, cat, grep, or any command that takes file arguments.

Wildcard Characters

Glob Patterns

PatternMatchesExample
*Any number of any characters (including zero)*.txt → all .txt files
?Exactly one any characterfile?.txt → file1.txt, fileA.txt
[abc]Any one character from the set[abc]*.txt → starts with a, b, or c
[a-z]Any one character in the rangefile[0-9].txt → file0 through file9
[!abc] or [^abc]Any character NOT in the set[!0-9]* → doesn't start with digit
{a,b,c}Brace expansion — generates strings (not a glob!){txt,md} → literally txt and md

* — Match Any Characters

ls *.txt                     # All files ending in .txt
ls data_*                    # All files starting with data_
ls *report*                  # All files containing "report"
ls *                         # All files (everything)

rm *.log                     # Remove all .log files
cp *.{jpg,png} ~/Pictures/   # Copy all jpg and png to Pictures
mv /var/log/nginx/*.log /backup/   # Move all nginx logs to backup

? — Exactly One Character

ls file?.txt                 # file1.txt, fileA.txt — NOT file10.txt (two chars)
ls ???.txt                   # Any 3-letter name with .txt extension
ls log?.conf                 # logA.conf, log1.conf, etc.
rm backup?.tar               # backup1.tar through backup9.tar, backupA.tar...

# Difference between * and ?
ls file*.txt                 # Matches file.txt, file1.txt, file10.txt, filename.txt
ls file?.txt                 # Matches ONLY file1.txt, fileA.txt (exactly one char)

[...] — Character Sets and Ranges

ls file[123].txt             # file1.txt, file2.txt, file3.txt ONLY
ls file[a-z].txt             # filea.txt through filez.txt
ls [A-Z]*.txt                # Files starting with uppercase letter
ls file[0-9][0-9].txt        # file00.txt through file99.txt

# Negated character sets
ls [!0-9]*                   # Files NOT starting with a digit
ls [^aeiou]*                 # Files not starting with a vowel

{} — Brace Expansion

Brace expansion is not a glob — it doesn't match existing files. Instead it generates strings, whether or not those files exist. This makes it useful for creating files, renaming patterns, and building command arguments.

# Generate multiple filenames
touch file.{txt,md,json}     # Creates file.txt, file.md, file.json
mkdir {frontend,backend}/{src,tests}  # Creates 4 directories
cp config.yaml{,.bak}        # Shorthand: copies config.yaml to config.yaml.bak

# Number ranges
touch file{1..5}.txt         # file1.txt through file5.txt
echo {A..Z}                  # A B C D ... Z
echo {01..10}                # 01 02 03 ... 10 (zero-padded)

# Nested braces
mkdir -p project/{src/{components,utils},tests/{unit,e2e}}

Combining Patterns

ls *.{jpg,png,gif}           # All image files
cp data_????_*.csv /backup/  # data_ + exactly 4 chars + _ + anything .csv
ls [A-Z]*.[ch]               # Uppercase-start C source or header files
find . -name "[!.]*"         # Files not starting with dot (non-hidden)

# Real-world: process all log files from Jan-Mar 2024
cat /var/log/nginx/access.log.2024-0[1-3]*  # Jan=01, Feb=02, Mar=03

Quick Check

You want to match `file1.txt`, `file2.txt`, and `file3.txt` but NOT `file10.txt` or `file.txt`. Which glob is correct?

Exercise

Create test files and practice globbing:

touch file{1..5}.txt fileA.txt fileB.txt data_report.csv notes.md
  1. List only the numbered files: file1.txt through file5.txt
  2. List files starting with file and ending with .txt (including fileA, fileB)
  3. List only file1, file2, file3 (not fileA, fileB, file4, file5)
  4. List all files that are NOT .txt files
  5. Create a backup of every .txt file in one command using brace expansion