The grep Command: Search Files and Logs Like a Pro
grep searches text for lines that match a pattern — in files, whole folders, or the output of another command. The examples you'll actually use: case-insensitive search, recursive search, line numbers, context around matches, counting, excluding folders, regex, and grepping logs, plus ripgrep.
grep prints the lines of text that contain a pattern. It's one of the most useful commands on Linux and Mac: find where a function is used, pull errors out of a log, check whether a config setting is there.
grep "error" app.log
That prints every line in app.log containing error.
The examples you'll actually use
Ignore upper/lower case (-i):
grep -i "error" app.log # matches Error, ERROR, error
Search a whole folder (-r, recursive) and show line numbers (-n):
grep -rn "DATABASE_URL" .
./src/db.ts:3:const url = process.env.DATABASE_URL
./.env.example:1:DATABASE_URL=postgres://...
Show context around each match — lines After, Before, or both (C):
grep -n -C 3 "TypeError" app.log
Count matches (-c) or just list files that match (-l):
grep -c "POST /login" access.log
grep -rl "useEffect" src/
Invert — show lines that don't match (-v):
grep -v "health" access.log # hide health-check noise
Whole words only (-w):
grep -w "id" schema.sql # matches "id", not "user_id"
Skip folders you don't care about:
grep -rn "TODO" . --exclude-dir=node_modules --exclude-dir=.git
Grep the output of other commands
The pipe | sends one command's output into grep:
ps aux | grep node # is my node process running?
docker ps | grep postgres
history | grep "ssh " # find that ssh command you ran last week
journalctl -u myapp | grep -i error
(Basic Linux Commands, What Is systemd?)
Patterns (regular expressions)
grep understands regular expressions. Use -E for the modern syntax:
grep -E "error|warn" app.log # either word
grep -E "^2026-10-0[1-9]" app.log # lines starting with a date
grep -E "[0-9]{3}\.[0-9]+\.[0-9]+" f # rough IP-like pattern
Quote your patterns so the shell doesn't interpret characters like * or |. Use -F to search for text literally, with no regex meaning. (Regular Expressions for Beginners)
Following a live log
Combine with tail -f to watch only matching lines as they arrive:
tail -f app.log | grep --line-buffered "ERROR"
ripgrep: a faster grep for code
ripgrep (rg) does the same job but is faster, searches recursively by default, and skips files in .gitignore (so no node_modules noise):
rg "DATABASE_URL"
rg -i "todo" src/
It's what many editors and coding agents, including Claude Code, use under the hood to search codebases.
The summary
grep "text" fileprints matching lines.-iignore case,-rrecursive,-nline numbers,-C 3context,-vinvert.- Pipe other commands into it, and try
rgfor searching code.
EasySpawn puts your app's logs on the same server as Claude Code, so "grep the logs for what broke at 3 a.m." is something you can just ask for. See how it works or join the waitlist.
Related: Terminal for Beginners · Bash Scripting for Beginners · Structured Logging · Debugging for Beginners
Keep reading
"Python Is Not Recognized as an Internal or External Command": How to Fix It
On Windows, "'python' is not recognized as an internal or external command, operable program or batch file" (or "pip is not recognized") means Windows can't find Python on your PATH. How to check whether Python is installed, use the py launcher, add Python to PATH, turn off the Microsoft Store alias, and fix pip.
"You Have Divergent Branches" in git pull: What It Means and How to Fix It
"hint: You have divergent branches and need to specify how to reconcile them" means your local branch and the remote both have commits the other doesn't. What divergence is, the three options (merge, rebase, fast-forward only), which to pick, and how to set a default so git stops asking.