# Wildcards: \*, ? and \[ \]

A wildcard pattern such as \*.jpg stands for every name that fits it, and the shell swaps in those names before the command runs, so echo shows you the list first and one mv moves every photo at once.

Apprentice · Unix · Linux · Updated November 10, 2026

## After this lesson you can

- Predict which names a pattern with \*, ? or \[ \] matches
- Move or copy many files at once with a wildcard, checking the match with echo first

## Key takeaways

- * matches any run of characters, even none, so *.jpg means every name that ends in .jpg.
- ? matches exactly one character, and [ ] matches one character from a list or a range, such as [1-3].
- The shell swaps the pattern for the matching names before the command runs. echo and the pattern show you that list first.
- When nothing matches, bash hands the pattern over unchanged, and the command says there's no such file. zsh stops before running it.

You're back from a trip, and your Downloads folder has 300 new photos in it, mixed in with a lease and a stack of receipts. Moving them one at a time is 300 commands. A file manager can do it in one drag if you sort by type, click the first photo, Shift-click the last and check that no PDF got caught on the way. The terminal has a shorter way: describe the names you want, and let the shell find them.

## Set up the practice folder

The same mess as before, in a folder of its own. These lines are safe to run again:

```bash
mkdir -p ~/terminal-practice/wildcards && cd ~/terminal-practice/wildcards
mkdir -p photos music documents
touch IMG_2041.jpg IMG_2042.jpg IMG_2043.jpg IMG_2051.jpg beach-day.png
touch boarding-pass.pdf lease.pdf resume.docx road-trip-mix.mp3 rainy-day.mp3
touch receipt-2026-01.pdf receipt-2026-02.pdf receipt-2026-05.pdf receipt-2026-11.pdf
ls
```

```text
IMG_2041.jpg   boarding-pass.pdf  rainy-day.mp3        resume.docx
IMG_2042.jpg   documents          receipt-2026-01.pdf  road-trip-mix.mp3
IMG_2043.jpg   lease.pdf          receipt-2026-02.pdf
IMG_2051.jpg   music              receipt-2026-05.pdf
beach-day.png  photos             receipt-2026-11.pdf
```

## \*: any name that fits

A **wildcard** is a character that stands in for others, like the blank tile in a word game. The most useful one is `*` (read "star"), which matches any run of characters, even none. `*.jpg` (read "star dot jpg") means every name that ends in `.jpg`, and `receipt*` every name that starts with `receipt`. To see what a pattern matches, put it after `echo`, which prints whatever it's given:

```bash
echo *.jpg
echo receipt*
```

```text
IMG_2041.jpg IMG_2042.jpg IMG_2043.jpg IMG_2051.jpg
receipt-2026-01.pdf receipt-2026-02.pdf receipt-2026-05.pdf receipt-2026-11.pdf
```

A `*` skips names that start with a dot, so hidden files stay out of it. And a pattern matches capital letters exactly, on a Mac too: `*.jpg` doesn't match `SUNSET.JPG`.

## The shell does the matching

Here's why a wildcard works with any command: the shell swaps the pattern for the names before the command runs. Type `mv *.jpg photos/`, and bash looks in the folder, finds the four photos, and runs `mv IMG_2041.jpg IMG_2042.jpg IMG_2043.jpg IMG_2051.jpg photos/`. `mv` never sees the star. In your textbook this is called **globbing**, and a pattern such as `*.jpg` is a **glob**.

![The command mv *.jpg photos/ in three steps: what you type, the shell swapping *.jpg for the four names it found in the folder, IMG_2041.jpg, IMG_2042.jpg, IMG_2043.jpg and IMG_2051.jpg, and the mv command that finally runs with those four names](https://fsdtrainingmedia.blob.core.windows.net/public/images/2026/11/874ac0b170ea4630b6d8e6a2713b7070.webp)

That's what makes `echo` first a good habit: `echo` gets exactly the list the real command would get. Check the list, press the up arrow, change `echo` to the real command, and run it:

```bash
echo *.jpg *.png
```

```text
IMG_2041.jpg IMG_2042.jpg IMG_2043.jpg IMG_2051.jpg beach-day.png
```

```bash
mv *.jpg *.png photos/
mv *.mp3 music/
ls
```

```text
boarding-pass.pdf  music                receipt-2026-02.pdf  resume.docx
documents          photos               receipt-2026-05.pdf
lease.pdf          receipt-2026-01.pdf  receipt-2026-11.pdf
```

Seven files sorted with two commands, and 300 photos would take the same one line. `cp` takes wildcards the same way.

## ? and \[ \]: exactly one character

`?` (read "question mark") matches exactly one character, whatever it is. `[ ]` (read "brackets") matches one character from the list inside them, and a dash makes a range: `[1-3]` is 1, 2 or 3, and `[25]` is 2 or 5. The receipts are named by month, which makes them good for trying both:

```bash
echo receipt-2026-0?.pdf
echo receipt-2026-0[1-3].pdf
```

```text
receipt-2026-01.pdf receipt-2026-02.pdf receipt-2026-05.pdf
receipt-2026-01.pdf receipt-2026-02.pdf
```

`0?` matched every month from 01 to 09 that's there, and `0[1-3]` only January to March: the first quarter of the year, ready to move into a folder of its own.

## When nothing matches

There are no videos in this folder. Here's what a pattern that matches nothing does:

```bash
echo *.mp4
mv *.mp4 music/
```

```text
*.mp4
mv: cannot stat '*.mp4': No such file or directory
```

When nothing matches, bash hands the pattern over unchanged. `mv` looks for a file that's really named `*.mp4`, finds none and says so (*cannot stat* means it couldn't look the file up). Nothing moves, and nothing breaks. zsh, the shell on a Mac, is stricter: it stops before running the command at all, with an error saying no matches were found. Either way, the message means the same thing: check your pattern.

## Try it in the terminal

[Terminal Quest: Moving Day, goals 3 to 4](https://www.ask-codey.com/games/terminal-quest/new-place/bash/step): played right on the lesson page.

There's a bookshelf in the living room now. Put every book on it with one command, then empty the whole kitchen box into the kitchen.

## Check yourself

2 questions to try on the lesson page.

## So what

A wildcard turns "every photo", "every receipt from March" or "everything in this box" into one short pattern. With `echo` first, you see exactly which files a command will touch before it touches them.

## Key terms

- [Wildcard](https://www.ask-codey.com/glossary/wildcard)
- [Glob](https://www.ask-codey.com/glossary/glob)
- [echo](https://www.ask-codey.com/glossary/echo)

## Cheat sheets

- [Wildcards: \*, ? and \[ \]](https://www.ask-codey.com/cheat-sheets/bash-wildcards-cheat-sheet)

## Related

- [Copy, Move and Rename: cp and mv](https://www.ask-codey.com/lessons/bash-copy-move-rename)
- [Brace Expansion: Twelve Folders in One Line](https://www.ask-codey.com/lessons/bash-brace-expansion)

Source: https://www.ask-codey.com/lessons/bash-wildcards
