LearnWithShobhan

Linux wildcards explained: *, ? and [ ] (globbing) with real examples

Shobhan Biswas··4 min read
>_From the course CLI Mastery: 57 lessons, lifetime access.

Typing a file name is fine when you have three files. When you have three hundred, you need a way to say "every file that looks like this". That is what wildcards (also called glob patterns) are for.

Once you know four symbols, ls *.txt, rm photo-0?.jpg and cp *.log backup/ become second nature.

The three symbols you will use daily

SymbolMatchesExample
*Zero or more characters*.txt matches cat.txt, big-file.txt
?Exactly one characterfile-?.txt matches file-1.txt, not file-10.txt
[ ]One character from a set or rangefile-[1-2].txt matches file-1.txt and file-2.txt

Let's try them on a folder with six files:

bash
$ ls
big-file.txt cat.txt file-1.txt file-10.txt file-2.txt file-3.pdf
bash
$ ls *.txt
big-file.txt cat.txt file-1.txt file-10.txt file-2.txt
$ ls file-*
file-1.txt file-10.txt file-2.txt file-3.pdf
$ ls file-?.txt
file-1.txt file-2.txt
$ ls file-[1-2].txt
file-1.txt file-2.txt

Here is the same experiment as a grid, so you can see which pattern catches which file:

Grid showing which of six files match the patterns star dot txt, file dash star, file dash question mark dot txt, file dash one-to-two dot txt and file dash one comma three dot star
Each column is a pattern, each row is a file. A tick means the pattern matches.

Notice why big-file.txt is not matched by file-*: a pattern has to match the whole name, and that name starts with big-.

? counts characters

file-?.txt skips file-10.txt, because after file- there are two characters (10) and ? stands for exactly one. This is the difference between * (any length) and ? (one slot).

Brackets: a set or a range

Whatever is inside [ ] is a list of allowed characters for that one position. Do not put commas inside:

ls file-[12].txt       # file-1.txt and file-2.txt
ls file-[1-3].txt      # a range: 1, 2 or 3
ls report-[a-c].md     # report-a.md, report-b.md, report-c.md
ls file-[!1].txt       # anything except 1 (use ! to negate)

Curly braces: a list of exact words

Braces are close cousins: you list the alternatives with commas, and the shell builds a name for each.

bash
$ ls file-{1,3}.*
file-1.txt file-3.pdf
$ mkdir -p project/{src,tests,docs}

The second command creates three folders at once. Strictly speaking braces are expanded by the shell before globbing, which is why they also work with commands like mkdir where no file exists yet.

The important part: the shell expands the pattern, not the command

When you type ls *.txt, the program ls never sees the star. The shell replaces the pattern with the list of matching names, then runs the command. You can prove it with echo:

bash
$ echo *.txt
big-file.txt cat.txt file-1.txt file-10.txt file-2.txt

This single fact explains a lot of behavior:

  • It works with every command: cp, rm, mv, cat, grep, your own scripts.
  • If nothing matches, Bash passes the pattern through unchanged (the command then complains it cannot find a file called *.xyz), while Zsh stops with no matches found.
  • To search for a literal star, quote it: grep '*' notes.txt. Quotes stop the shell from expanding.
  • * does not match hidden files (names starting with a dot), so ls * will not show .env.

Use wildcards with the commands you already know

bash
$ cp *.log backup/
$ mv photo-0?.jpg 2026/
$ cat chapter-[1-3].md > book.md
$ rm -r test-dir-*

Cheat sheet

PatternMeaning
*.txtEvery file ending in .txt
file-*Every name starting with file-
file-?.txtfile- plus exactly one character, then .txt
file-[1-3].txtfile-1, file-2 or file-3
file-[!1].txtOne character that is not 1
file-{a,b}.txtExactly file-a.txt and file-b.txt
'*' (quoted)A literal star, no expansion

Key takeaways

  • ✓* means any number of characters, ? means exactly one, [ ] means one character from a set or range.
  • ✓The shell expands the pattern into file names before the command starts. The command never sees the wildcard.
  • ✓Braces {a,b} list exact alternatives, with commas. Brackets [ab] never use commas.
  • ✓A pattern must match the whole name, and * skips hidden files.
  • ✓Run the pattern with ls or echo first, then use it with rm.

Where wildcards lead

Patterns become really powerful once commands can be chained. The very next skills are pipes and redirection, then shell scripts that process whole folders of files. CLI Mastery takes you through that sequence, 57 lessons, lifetime access. Start with the free pipes lesson.

Free download

Linux command line cheat sheet

One printable page: navigation, files, permissions, pipes, processes, scripts and SSH.

Occasional emails with new tutorials and courses. Unsubscribe any time.

Keep reading