Glob#
Glob patterns are the simpler, older cousin of regex: a small pattern
language for matching filenames. Used by the shell, .gitignore,
rsync, find -name, build tools, and more.
Core Syntax#
A small alphabet, five or six metacharacters that cover
nearly every filename-matching task. Glob trades regex’s
expressive power for simpler reading and stricter path
semantics; wildcards stop at directory separators unless the
extended ** is enabled.
Pattern |
Matches |
|---|---|
|
any sequence of characters (excluding |
|
a single character (excluding |
|
one of the characters |
|
range |
|
not one of (some shells use |
|
any number of path segments (extended glob) |
|
brace expansion, one of |
*does not match path separators by default.Hidden files (
.foo) are usually not matched by*– enabledotglob/ equivalent if needed.
Examples#
A handful of common patterns that show up across shells, build
tools, ignore files, and find invocations. Each one is
worth recognizing on sight; together they cover most of the
patterns operators write in a typical week.
Pattern |
Matches |
|---|---|
|
text files in the current directory |
|
Go files directly in |
|
Go files at any depth under |
|
|
|
files starting with |
|
any of these extensions |
|
negation in |
Glob vs. Regex#
The two pattern languages serve different jobs. Glob is for filenames, regex is for arbitrary text. Reading a glob pattern is easier; writing one keeps the operator out of escape-character traps that regex routinely sets. The list below codifies the dividing line.
Glob is much smaller; only
*,?, and character classes plus some extensions.Glob is anchored to the whole path by default; regex is by default partial.
Glob has no quantifiers, alternation (without brace expansion), or groups.
Regex is more powerful and harder to read.
When matching filenames, glob is almost always the right tool.
Extended Glob (**)#
Recursive matching across path segments.
src/**/*.test.ts # any depth under src/
**/node_modules # any node_modules at any depth
docs/**/index.md # any index.md anywhere under docs/
Most modern tools (npm scripts, Bazel, Bun, fast-glob, gitignore)
support **. POSIX shells need shopt -s globstar (Bash) or
setopt extendedglob (Zsh).
.gitignore Patterns#
The dialect every developer touches most often. Git’s ignore files extend plain glob with negation, directory-only matches, and anchoring rules that let one short file describe which files are tracked and which are not, across deeply nested trees.
Git’s pattern format extends glob with negation and anchoring.
# comment
*.log # any .log file at any depth
/build/ # only the top-level build/
!important.log # un-ignore (negation)
docs/**/*.bak # backup files under docs/
Rules.
Trailing
/, match directories only.Leading
/, anchor to the root.No leading
/, match at any depth.!, re-include something previously excluded.
Brace Expansion#
A separate but adjacent feature, not strictly part of glob.
{jpg,png,gif} # alternation
file_{1,2,3}.txt # generates three names
[0-9] # character class
{01..05} # numeric range (Bash)
Brace expansion happens before glob matching in most shells.
Where Glob Appears#
Glob is everywhere there’s a list of filenames to filter – shells, ignore files, sync tools, build systems, editor configs. The list below is a reminder of how broad the footprint is, and why glob is one of the highest-leverage DSLs to keep fluent.
Shells,
ls *.txt,rm -rf node_modules/*.`.gitignore` / `.dockerignore` / `.gcloudignore`.
rsync,
--include/--exclude.find,
find . -name '*.go'.Build tools,
glob/filegroupin Bazel;include/excludein npm and many others.Editor configurations,
.editorconfig, VS Code’sfiles.exclude.
Pitfalls#
The traps that catch operators new to glob, or operators
crossing between shells and tools. Quoting, dotfile handling,
** opt-in semantics, and special-character escaping are
the four that come up over and over, each easy to fix once
spotted.
Quote your patterns in shell when they shouldn’t be expanded by the shell itself:
find . -name '*.txt'.``**`` requires opt-in in many shells.
Hidden files,
*doesn’t match dotfiles by default.Escape special chars in filenames you want to match literally.
Libraries#
Per-language glob implementations. Coverage of the extended
features (**, brace expansion, negation) varies, so the
exact library matters when patterns travel across runtimes.
The table below points at the standard or most widely used
choice in each language.
Node,
fast-glob,micromatch,minimatch,picomatch.Python,
glob(stdlib),pathlib.Path.glob,fnmatch.Go,
filepath.Glob(no**),doublestar.Rust,
globcrate,globset.Java,
FileSystem.getPathMatcher.
Different libraries support different extensions; check the docs before
relying on ** or brace expansion.