<aside> 🔍
Module 6 — Finding Things: find and grep
Two questions dominate real operations work: where is the file? and which files contain this? find answers the first by walking the tree; grep answers the second by reading contents. Between them sits the skill interviewers probe hardest — regular expressions. This module goes deep on all three; its sibling, Module 7, does the same for editing text.
Legend used throughout: 🧠 concept → 🧩 analogy → 🧪 exercise → ✅ expected result (hidden) → 🎯 interview questions (hidden)
</aside>
<aside> 🚦
Before you start
You need Modules Module 1 — What Linux Is–Module 5 — The Shell, Properly — pipes, exit codes, quoting, and globbing are load-bearing here. Build the playground by pasting this whole block (the cat > file <<'EOF' construct collects the lines you paste, until the EOF line, into the file — a Module 10 construct on early loan):
mkdir -p ~/search/app/logs ~/search/app/config ~/search/notes
cd ~/search
cat > app/logs/app.log <<'EOF'
2026-09-02 10:00:01 INFO Service starting
2026-09-02 10:00:02 INFO Config loaded from /etc/app/app.conf
2026-09-02 10:03:15 WARN Slow response from db-01 (1200ms)
2026-09-02 10:04:44 ERROR Connection to db-01 refused
2026-09-02 10:04:45 ERROR Retry 1 failed: connection refused
2026-09-02 10:04:47 error retry 2 failed: connection refused
2026-09-02 10:05:00 INFO Failover to db-02
2026-09-02 10:05:01 INFO Connection to db-02 established
EOF
cat > app/config/app.conf <<'EOF'
listen_port=8080
db_host=db-01
db_port=5432
# temporary override
db_host_backup=db-02
EOF
echo 'remember: rotate keys' > notes/todo.txt
touch -d '2 days ago' notes/old.txt
</aside>
<aside> ℹ️
This page uses Mermaid diagram blocks. Notion shows them as code by default — click the block and set it to Preview to see the diagram. This reminder appears once per page.
</aside>
<aside> 📖
Official docs: grep(1) — print lines that match patterns
</aside>
🧠 grep pattern file prints every line containing a match for the pattern. The daily options: -i ignore case, -n show line numbers, -c count matching lines instead of printing them, -w match whole words only. And one behaviour that matters enormously to automation: grep's exit code speaks (Module 5): 0 — found something; 1 — found nothing (not an error!); 2 — actual trouble (unreadable file). "No matches" being exit 1 makes grep a test you can build conditions on — and a trap inside strict scripts, revisited in this module's tickets.
<aside> 🧩
Real-world analogy — the assistant with the highlighter
Hand an assistant a 400-page transcript: "copy out every line that mentions the defendant". Back comes one tidy page of quotes. grep is that assistant — tireless, literal, and done in milliseconds.
Where the analogy stops working. A human assistant copies the surrounding sentences when a quote would mislead alone. grep copies exactly the matching lines and nothing else — context is lost unless you explicitly ask for it (A4), and a match mid-word is still a match unless you say -w.
</aside>
🧪 Exercise A1.1 — First reads of a real log
cd ~/search
grep ERROR app/logs/app.log
grep -i error app/logs/app.log # case-insensitive: catches the sloppy lowercase line
grep -c -i error app/logs/app.log # just the count
grep -n refused app/logs/app.log # with line numbers
<aside> 📖
Official docs: grep(1)
</aside>
🧠 -v inverts: print lines that do not match. And because grep reads stdin when given no file, it slots into Module 5's pipelines as the universal filter: command | grep pattern | grep -v noise. Include-then-exclude chains read like sentences: "lines about the db, but not the healthy ones".
<aside> 🧩
Real-world analogy — the two-door screening
Airport security in two stages: the first door admits only ticket-holders (include), the second pulls aside anyone on the fast-track list (exclude). Chaining greps is stacking doors; each stage sees only what the previous one passed.
Where the analogy stops working. Doors screen people one at a time in order of arrival; a grep chain preserves line order but each stage is a separate process running concurrently (Module 5's pipes) — the second door is already screening while the first is still admitting. Also: -v rejects whole lines — there is no "remove just the bad word", which is Module 7's job (sed).
</aside>
🧪 Exercise A2.1 — Sculpt the log down to the incident
cd ~/search
grep -v INFO app/logs/app.log # drop the routine chatter
grep -i error app/logs/app.log | grep -v Retry # errors, but not the retries
env | grep -i home # filter ANY command's output