Using Zsh Glob Qualifiers to Filter Files by Size and Time
Learn how zsh glob qualifiers let you filter files by size, age, type, and more directly in a pattern, avoiding external pipelines.
12 Sept 2026, 04:57 UTC

Problem: selecting files without external tools
You often need to pick the newest log file, the largest image, or all files modified today. In many shells you would reach for find, sort, and head pipelines, which can be cumbersome for interactive work.
Thesis: zsh glob qualifiers let you filter by attributes directly in the pattern
Glob qualifiers are a zsh‑specific extension that attaches conditions to a filename pattern inside parentheses. They are evaluated by the shell’s glob engine, so the result is produced without spawning external processes.
Syntax basics
A qualifier list appears after the pattern, enclosed in parentheses. Multiple qualifiers can be combined, order does not matter.
pattern(.qualifier1 qualifier2 ...)
For the qualifiers to be recognised, the option extended_glob must be set (it is on by default in many interactive configurations).
Common qualifiers
.– regular file/– directory@– symbolic link-– size in bytes (prefix with+for larger,-for smaller)m– modification time in days (similar prefix syntax)O– order by modification time newest first (O1gives the newest match)o– order by modification time oldest firstn– numeric sort (useful with versioned filenames)N– null‑glob: return empty list instead of error when nothing matches
Worked example: find the five newest PNG images in a tree
Assume you have a directory ~/photos with subfolders and many .png files.
# Enable the option if not already active
setopt extended_glob
# List the five newest PNG files
print -l **/*.png(.nO5)
Explanation:
**/*.pngmatches any.pngfile anywhere under the current directory.(.nO5)adds three qualifiers:.restricts to regular files (excludes directories named.png).nsorts numerically, ensuringimg10.pngcomes afterimg2.png.O5orders newest first and limits the result to the first five entries.
You can verify the ordering by checking timestamps:
stat -c '%Y %n' **/*.png(.nO5) | sort -nrTrade‑offs and limitations
- Performance: The shell evaluates qualifiers for every candidate match. On a filesystem with millions of files, a broad pattern like
**/*can become noticeable; limit the scope with directory prefixes when possible. - Units: The size qualifier
-uses bytes, not the 512‑byte blocks used by somefindimplementations. Double‑check if you are converting from afindcommand. - Null‑glob behaviour: If no file matches and
null_globis unset, zsh prints an error like "zsh: no matches found". Settingsetopt null_globmakes the expression expand to an empty list, which is safer in scripts. - Portability: Glob qualifiers are zsh‑only; scripts that rely on them will not run in bash or dash without modification.
Getting started
- Open a zsh session.
- Ensure extended globbing is active:
setopt extended_glob(add to~/.zshrcfor permanence). - Create a small test set to experiment:
- Try a few qualifiers and compare with
find: - Check results manually if you wish (e.g.,
ls -lorstat) to confirm the shell’s output matches expectations.
mkdir -p /tmp/zsh-test
cd /tmp/zsh-test
for i in {1..5}; do
touch -t 2024010${i}0000 file$i.txt
dd if=/dev/zero of=big$i.bin bs=$((i*100)) count=1 2>/dev/null
done
# Newest .txt file
echo *.txt(.Om1)
# Files larger than 250 bytes
echo *.(.s+250)
# All regular files, sorted by size descending
echo *(.OL)
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.