MainspringGuides › grep command
macOS Guide

grep on Mac: Search Inside Files From Terminal

Updated July 2026 · 3 min read

Finder and Spotlight find files by name; grep finds the line inside a file where something is written. It searches one file, a folder tree, or the output of another command, and it's on every Mac. Four or five flags cover almost everything you'll ever ask of it.

One file, then whole folders

The shape is grep 'pattern' where. Quote the pattern so spaces and special characters survive the shell:

# lines containing "error" in one file
grep 'error' ~/Library/Logs/install.log

# search every file under a folder, recursively
grep -r 'API_KEY' ~/Projects

# case-insensitive: matches Error, ERROR, error
grep -ri 'error' ~/Projects/logs

-r recurses into subfolders and prints the file name in front of every match; -i ignores case. Together they turn grep from a one-file tool into "search my whole project."

When a recursive search sweeps too many file types, narrow it with --include: grep -r --include='*.swift' 'TODO' ~/Projects reads only Swift files and skips everything else, which makes a real speed difference in folders full of images or build products. Quoting matters here too — keep patterns in single quotes so the shell passes them through untouched, and reach for double quotes only when you deliberately want a shell variable expanded inside the pattern.

Flags that make results readable

# which config files mention "timeout", with line numbers
grep -rn 'timeout' ~/Projects/config

# just the file names
grep -rl 'timeout' ~/Projects/config

grep only reads plain text. On a binary file it prints Binary file … matches instead of the line — that's expected, not an error. Word processor documents, PDFs, and Numbers files won't grep usefully; export to text first.

-C has two siblings worth knowing: -A 3 shows three lines after each match (useful for reading what follows an error) and -B 3 shows three lines before it. On huge files, -m 5 stops after the fifth match so you aren't buried in output.

A little regular-expression knowledge multiplies all of this. ^ anchors a match to the start of a line and $ to the end, so grep '^import' finds lines that begin with the word rather than merely contain it. For alternatives, add -E for extended syntax: grep -E 'error|warning' matches either word. One Mac-specific caveat: macOS ships BSD grep, not the GNU version Linux tutorials assume, so Perl-style shortcuts like \d aren't supported — write [0-9] with -E instead.

Pipe other commands into grep

grep's second life is as a filter. Any command's output can be piped through it:

# is Safari running, and with what process ID?
ps aux | grep -i safari

# every command you've run mentioning ssh
history | grep 'ssh'

# find one setting in a wall of system values
sysctl -a | grep machdep.cpu.brand_string

This pattern — verbose command | grep the bit you care about — is the single most common Terminal idiom on the Mac. Once it clicks, every command that prints too much becomes searchable. macOS also includes zgrep, which searches inside gzip-compressed files directly — handy for rotated logs ending in .gz under /var/log without decompressing them first.

Less Terminal, same power

Enjoy this kind of control? Mainspring turns 90+ hidden macOS settings into labelled, reversible toggles — the Terminal-only tweaks, minus the syntax and with a built-in undo.

Try Mainspring free →

Signed & notarized by Apple · 1-day free trial · $29 once

Names versus contents

grep answers "which files contain this text?" — its natural partner answers "which files have this name, size, or age?" Combine the two and you can locate nearly anything; see the find command on Mac for the name-and-metadata half.