<aside> 🧵

Module 11 — Text Processing in Pipelines. grep, cut, sort, uniq, tr, xargs, sed, awk — the tools behind almost every log-analysis one-liner asked in interviews.

🧠 concept → 🧩 analogy → 🧪 exercise → ✅ expected result (hidden) → 🎯 interview questions (hidden)

</aside>

<aside> 📋

Before you start. You need Modules 1–10 — pipelines and streams above all (Module 4: every tool here is a pipe segment), plus grep-as-verdict (Module 3) and the glob-vs-regex boundary (Module 9 drew it; this module crosses it). One promise comes due: Module 5 taught you =~ "as a recipe" — regex gets its survival kit here. Setup: the exercises share one small fake log; Exercise 11.1 creates it.

</aside>

Part A — grep, and enough regex to be dangerous

A1. grep beyond the verdict

<aside> 📖

Official docs: grep(1) — man7.org

</aside>

Module 3 used grep -q purely for its exit code. Full grep prints every matching line — it is the fleet's search engine, and four options do most of the daily work: -i (ignore case), -v (invert: lines that do not match), -c (count matching lines instead of printing them), -n (prefix line numbers). It reads files by name or, as a pipe segment, its stdin — same tool, both mouths.

🧪 Exercise 11.1 — build the lab, then search it

cd ~/bash-course && mkdir -p textlab && cd textlab
cat > access.log <<'EOF'
203.0.113.9 - GET /index.html 200
198.51.100.7 - GET /api/users 200
203.0.113.9 - POST /api/login 401
192.0.2.44 - GET /index.html 200
203.0.113.9 - POST /api/login 401
198.51.100.7 - GET /api/orders 500
192.0.2.44 - GET /style.css 200
203.0.113.9 - POST /api/login 401
198.51.100.7 - GET /api/orders 500
203.0.113.9 - GET /admin 403
EOF
grep 401 access.log
grep -c 401 access.log
grep -v 200 access.log | wc -l

A2. The regex survival kit

<aside> 📖

Official docs: grep(1) — man7.org (see its REGULAR EXPRESSIONS section)

</aside>

grep's patterns are regular expressions — a different, more powerful language than Module 2's globs, and the difference bites exactly once per career: in regex, * does not mean "anything" (that's .*) and . is not a literal dot (that's \.). The survival kit, seven pieces: ^ start of line · $ end of line · . any one character · [abc]/[0-9] one character from a set · * zero-or-more of the previous thing · + one-or-more (needs grep -E, the extended dialect) · a|b alternatives (also -E). That kit covers the vast majority of operational grepping, and it is the same language [[ =~ ]] spoke in Module 5 — that recipe (^[0-9]+$: start, digits, one-or-more, end) now reads as a sentence.

<aside> 🧩

Real-world analogy — the police sketch. A glob is a wanted poster with a photo and a wildcard hat: crude shape-matching. A regex is the police sketch artist's interview: "starts with… then any digit, repeated… nothing after" — a description language precise enough to match faces you have never seen. ^ERROR .*timeout$ is a sketch: begins with ERROR, anything in the middle, ends in timeout.

Where the analogy stops working. A sketch artist knows which features matter. Regex has no judgment: . matches any character including the dot you meant literally, so 192.0.2.44 as a pattern also matches 192x0y2z44. In operational grepping over IPs and versions, escape your dots (192\.0\.2\.44) — and when a colleague's grep matches "too much," the unescaped dot is suspect number one.

</aside>

🧪 Exercise 11.2 — sketches against the log

cd ~/bash-course/textlab
grep -E 'POST|500' access.log
grep -c '^203' access.log
grep '00$' access.log | wc -l

Interview questions — Part A

Part B — The column tools: cut, sort, uniq, tr