VMware ESXi and vSphere Cluster Management
Linux Wildcards: Shell Globbing with *, ?, and Brackets
Learn how Linux shell wildcards such as *, ?, and bracket expressions select filenames, expand in commands, and can be used safely.
What Linux wildcards do
A wildcard is a special pattern symbol that helps select matching filenames and pathnames. In Linux shells, these patterns are commonly called globs.
Before a command such as ls, cp, mv, or rm runs, the shell usually performs pathname expansion: it replaces a matching pattern with the matching filenames. The command then receives those filenames as separate arguments.
ls -- *.txtIf the current directory contains notes.txt and todo.txt, the shell effectively runs:
ls -- notes.txt todo.txtShell globs are different from regular expressions. Both are pattern languages, but their syntax and purpose differ. A shell glob selects pathnames, while a regular expression is commonly used to search or validate text with tools such as grep.
Core Linux wildcard symbols
| Pattern symbol | Meaning | Characters matched | Example pattern | Example matching names |
|---|---|---|---|---|
? | Matches exactly one character | One character in one filename component | O??d | Oind, Okhd |
* | Matches zero or more characters | Any number of characters, including none | O*d | Od, Oad, Oereed |
[abc] | Matches one listed character | Exactly one character from the list | O[ac]d | Oad, Ocd |
[a-e] | Matches one character in a range | Exactly one character from a through e | O[a-e]d | Oad, Obd, Oed |
[!abc] | Matches one character not listed | Exactly one character other than a, b, or c | O[!a]d | Obd, Odd |
The question-mark wildcard: ?
The question mark matches exactly one character in a filename component. It is useful when a name has a fixed length or a fixed number of unknown positions.
O??dThis pattern requires a name to begin with O, end with d, and contain exactly two characters between them.
- Matches:
Oind,Okhd,Oerd - Does not match:
Od, because it has no characters betweenOandd - Does not match:
Oad, because it has only one middle character - Does not match:
Oereed, because it has more than two middle characters
Each ? accounts for one character. Therefore, three question marks would require exactly three characters in that position.
The asterisk wildcard: *
The asterisk matches zero or more characters. Unlike ?, it can match text of varying lengths, including an empty section.
O*dThis matches names beginning with O and ending with d, regardless of how many characters appear in the middle.
Odmatches because*can match zero characters.Oadmatches because*can matcha.Oindmatches because*can matchin.Oereedmatches because*can matcheree.
Common uses include prefixes, suffixes, and extensions:
backup* # names beginning with backup
*.txt # names ending with .txt
report*.log # names beginning with report and ending with .logA glob can contain more than one asterisk, such as 2026-*-backup.*. Each asterisk matches within its own filename component.
Bracket expressions
A bracket expression selects exactly one character from a set or range. It is written inside square brackets.
Character lists
O[ac]dThis matches Oad and Ocd. The bracket expression occupies one position, so it does not match Obd or Oaard.
Character ranges
O[a-e]dThe range a-e represents a, b, c, d, or e. The pattern matches:
OadObdOcdOddOed
Other examples include [0-9] for one digit and [A-Z] for one uppercase letter. A range selects one position; it does not behave like *.
Negated bracket expressions
A bracket expression can exclude characters. In many shells, [!a] means one character other than a. Some shells also accept [^a] for the same purpose. The ! form is generally the more portable shell spelling, but check the shell's documentation when portability matters.
[!a]*This selects visible names whose first character is not a, followed by zero or more additional characters.
Comparing similar patterns
| Pattern | Expected matches | Expected non-matches | Reason |
|---|---|---|---|
O??d | Oind, Okhd, Oerd | Od, Oad, Oereed | Each question mark matches exactly one character. |
O*d | Od, Oad, Oind, Oereed | A name not beginning with O or not ending with d | The asterisk matches zero or more characters. |
O[ac]d | Oad, Ocd | Obd, Oaard | The bracket list allows one character, either a or c. |
O[a-e]d | Oad, Obd, Ocd, Odd, Oed | Ofd, Oabd | The range allows one character from a through e. |
Practicing in an isolated directory
Use a test directory so experiments do not affect important files.
mkdir -p wildcard-practice && cd wildcard-practice
touch Od Oad Ocd Obd Oind Okhd Oerd Oereed notes.txt report1.log report2.log .hiddenPreview the results of several patterns:
printf '%s\n' -- O??d
printf '%s\n' -- O*d
printf '%s\n' -- O[ac]d
printf '%s\n' -- O[a-e]dThe shell expands each unquoted pattern before printf receives it. The -- argument is a conventional separator that helps distinguish data from options in commands that support it.
Using globs with commands
Inspecting files with ls
ls -- *.txt
ls -- backup*
ls -d -- .*The first command lists visible text files. The second lists visible names beginning with backup. The explicit dot pattern in the third command selects dot-prefixed entries, but it can also include . and ..; handle its output carefully.
Copying and moving
cp -- *.txt ../text-backups/
mv -- report?.log archived/If a pattern expands to several names, cp or mv receives all of them. For a multi-source operation, the destination normally must be a directory.
Removing files
rm -- *.tmpPreview first:
printf '%s\n' -- *.tmp
ls -l -- *.tmp
rm -- *.tmpImportant globbing behavior
A glob does not cross a slash
Normal wildcard matching occurs within one directory-name component. An asterisk does not normally cross a slash.
*.txtThis selects text files in the current directory, not text files inside every subdirectory. A pattern such as logs/* selects entries directly inside logs, but not entries in deeper directories. Recursive selection requires another tool or shell feature, such as an appropriately constructed find command.
Hidden names are normally excluded
A hidden file is a Unix filename beginning with a period. Patterns that do not begin with a period normally do not match such names. Thus, * normally excludes .hidden.
To explicitly select ordinary hidden entries, use a pattern beginning with a dot:
ls -d -- .*Because this can include . and .., use it with care. In Bash, shopt -s dotglob changes glob behavior so many ordinary globs can include dot-prefixed names. Shell options differ, so verify the behavior before using a modifying command.
When nothing matches
In many shells, an unmatched pattern is passed to the command unchanged. For example, if no file ends in .csv, printf '%s\n' -- *.csv may print the literal text *.csv. A command such as ls -- *.csv may instead report that a file named *.csv does not exist.
Bash can be configured with:
shopt -s nullglobWith Bash's nullglob option, an unmatched pattern expands to zero arguments. This can be useful in scripts, but scripts must still handle the possibility that a command receives no filenames.
Quoting and escaping
Quoting preserves characters as literal text. Single and double quotes suppress pathname expansion:
ls -- '*.txt'This asks ls to look for a literal filename named *.txt; it does not select all text files. A backslash is an escape that makes the following special character literal:
printf '%s\n' 'file*name' file\*nameBoth arguments retain the asterisk rather than expanding it. Leave a glob unquoted when you want the shell to expand it, and quote literal text or variable expansions when needed.
Safe wildcard usage checklist
| Situation | Recommended action | Example |
|---|---|---|
| Previewing matches | Use printf or ls before changing files. | printf '%s\n' -- *.tmp |
| No files match | Check the directory and pattern; decide whether shell options such as Bash's nullglob are appropriate. | pwd, ls, shopt -s nullglob |
Filenames beginning with - | Place -- before expanded filenames when the command supports it. | rm -- --strange-name or rm -- *.tmp |
| Hidden files | Use an explicit dot pattern and remember that .* may include . and ... | ls -d -- .* |
| Removing files | Preview the exact expansion, then use the narrowest safe pattern. | ls -l -- *.tmp followed by rm -- *.tmp |
Troubleshooting wildcard problems
The command displays the pattern itself
The pattern may not match anything, or it may have been quoted or escaped.
- Check the current directory with
pwd. - List available names with
ls. - Inspect the command's pattern with
printf '%s\n' -- pattern. - Remove unintended quotes or backslashes only if expansion is desired.
A hidden file is missing
This is normal for a pattern such as *. Use an explicit pattern beginning with a period, or enable the relevant shell option with care.
A pattern matches too many files
The * operator allows an empty sequence and any number of characters. Replace it with ? for fixed positions or a bracket expression for restricted choices. Always preview the result.
Quotes prevent expansion
Single and double quotes suppress pathname expansion. Leave the intended glob unquoted, but continue to quote unrelated literal text and variable values appropriately.
A filename is interpreted as an option
A matched name beginning with - may be mistaken for a command option. Put -- before the expanded names, for example rm -- pattern.
Regular-expression syntax does not work
Shell globs and regular expressions are separate languages. Use glob syntax for shell pathname selection, and use the syntax documented by grep or another text-processing tool when matching file contents.
Exam-relevant points
?matches exactly one character.*matches zero or more characters.- A bracket expression matches one character from a list or range.
- Globbing normally happens in the shell before the command runs.
- Globs do not normally cross slashes.
- Patterns not beginning with a period normally exclude hidden names.
- Quoted or escaped wildcard symbols remain literal.
- An unmatched pattern may remain unchanged, depending on the shell and its options.
- One pattern can expand to many filenames, so preview it before using
rm,mv, or another modifying command.
For related pattern languages, see shell quoting, escaping, and filename pattern matching.