Zsh Extended Globbing: Powerful File Matching
Learn how zsh’s extended globbing lets you filter files by name, type, size, and even content directly in the shell, saving time and keeping scripts portable.
20 Oct 2025, 12:26 UTC

Problem: Repetitive File Filtering with External Tools
When working in a shell, you often need to list or act on a subset of files—say, all text files larger than 1 MB that contain a specific string. The usual approach is to pipe ls or find into grep and then into a loop. That adds extra processes, clutters the command line, and makes scripts harder to read.
Thesis: Extended Globbing Lets You Match Files In‑Place
zsh’s extended_glob option expands the shell’s pattern language. With it, you can embed qualifiers that filter by name, type, size, and even content—all inside a single glob expression. This keeps the script self‑contained and eliminates the need for external utilities.
How It Works: Qualifiers and Lazy Evaluation
(N)– match nothing (useful for negation)(D)– match directories(G)– match files whose size is greater than the following number of bytes(C)– match files whose contents match a pattern(/)– match only directories (same as(D))(.)– match regular files
When the shell parses a glob, it lazily walks the file system, applying qualifiers on the fly. This can be faster than building a full list in memory, especially in large directories.
Concrete Example: List .txt Files Larger Than 1 MB Containing “error”
# Enable extended globbing in a zsh session or script
setopt extended_glob
# Pattern explanation:
# *(.txt) – any file ending with .txt
# (G1048576) – size > 1,048,576 bytes (1 MB)
# (C(error)) – content contains the string "error"
# Run the glob and print matches
print -rl -- *(.txt)(G1048576)(C(error))
Run the snippet in a directory with sample files. If the output lists only the expected files, the pattern is working. You can also redirect the output to a file or pipe it to another command.
Verification Steps
- Start a new zsh session:
zsh - Enable the feature:
setopt extended_glob - Create test files:
echo "error" > a.txt truncate -s 2M b.txt printf "no error" > c.txt - Run the glob:
print -rl -- *(.txt)(G1048576)(C(error)) - Confirm only
b.txtappears. Ifa.txtalso shows up, check the size qualifier.
Trade‑Offs and Limitations
- Non‑portable – The syntax is unique to zsh. Scripts that rely on it will fail under bash, sh, or dash unless you guard with a
[[ $ZSH_VERSION ]]check. - Learning curve – The qualifiers can be confusing. A stray parenthesis or missing qualifier can silently match nothing or everything. Always test patterns in a safe environment.
- Complexity vs. Simplicity – For very simple filters, a short
findcommand may be clearer to readers unfamiliar with zsh.
Actionable Closing
To adopt extended globbing in your workflow:
- Add
setopt extended_globto the top of any zsh script that needs complex file matching. - Use qualifiers sparingly; start with basic name and type filters before adding size or content checks.
- Document each pattern with a comment explaining the qualifiers, so future maintainers can understand the intent.
- When porting scripts to other shells, replace glob patterns with equivalent
findorgrepcommands.
With these steps, you’ll write concise, efficient, and self‑contained zsh scripts that keep external dependencies to a minimum.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.