Course outline · 0% complete

0/29 lessons0%

Course overview →

Searching a whole project: grep -r and simple patterns

lesson 4-3 · ~9 min · 12/29

grep across many files

Real projects are hundreds of files. Questions like "where is this function used?" or "which files still say TODO?" can't be answered one file at a time — and this is the search that working engineers run many times a day (every editor's project-wide search box is a version of it). grep has flags for exactly this:

  • grep -r pattern directory: recursive — search every file in the directory and all its subdirectories. Each match prints as path:matching line, so you know which file it came from.
  • grep -rn pattern .: add line numbers too; path:line:text is the exact address of every match.
  • grep -rl pattern .: print only the list of file names that contain a match, one per line — for when the question is "which files", not "which lines".

Code exercise · bash

Run it. We build a tiny project with a TODO note in two different files, then one grep -rn finds both without being told where to look. (The | sort makes the order predictable — grep visits files in whatever order the filesystem returns them.)

Patterns, not just words

The pattern you give grep is not plain text — it's a regular expression (regex for short): a small language for describing the shape of text. So far you've used the boring subset, where letters match themselves. Four symbols unlock the useful subset:

symbolmatches
^the start of the line
$the end of the line
.any single character
[abc]one character from the set

So ^error matches lines that begin with error (not lines that merely mention it), and full$ matches lines that end with full. Quote the pattern — grep '^error' file — so the shell passes it to grep untouched, the same reason find's pattern was quoted in lesson 4-2.

Regular expressions go much deeper (they deserve a course of their own), but ^ and $ alone sharpen a large share of real searches.

Code exercise · bash

Run it. A plain `grep error` would match three of these lines. Anchoring with ^ keeps only the lines that START with error, and full$ finds the one line that ENDS with full.

Quiz

In a grep pattern, what does `^` mean?

Code exercise · bash

Your turn. The starter writes a 5-line events.log. Print every line that STARTS with `user`, then print how many lines END with `ok` (lesson 4-1's -c counts matches). Expected output: ``` user alice logged in user bob logged in 2 ```