grep options: -i, -n, -v, -c, -r
Ignore case, show line numbers, invert the match, count instead of print, and search whole directory trees.
What you will learn
- Combine -i, -n, -v and -c and predict what each combination prints.
- Search recursively with -r and list only file names with -l.
- Match whole words with -w and show context with -A, -B and -C.
Plain grep answers "which lines contain this?". Its options let you ask the neighbouring questions: how many, which ones do *not*, where exactly, in which files. They are single letters and they combine freely, so grep -inv is as valid as grep -i -n -v. Here are the ones you will use every week, all supported by the BusyBox grep in this VM.
Case, numbers, inversion, counting
| Option | Effect |
|---|---|
-i | ignore case: error matches Error and ERROR |
-n | prefix each line with its line number |
-v | invert: print the lines that do NOT match |
-c | print only the count of matching lines |
-w | match whole words only |
-x | match whole lines only |
-o | print only the matching part, not the whole line |
-v is the one people forget and then reinvent badly. "Show me the config without the comments" is grep -v '^#' file; "the log without the DEBUG noise" is grep -v DEBUG app.log. -c counts lines, not occurrences: a line with the word twice counts once. -w stops grep cat from matching concatenate, by requiring the match to be bounded by non-word characters.
~% cd /root/lab/l32
l32% cat app.log
INFO service started
error: config not found
DEBUG retrying
Error: disk full
INFO done
l32% grep -in error app.log
2:error: config not found
4:Error: disk full
l32% grep -c INFO app.log
2
l32% grep -v DEBUG app.log
INFO service started
error: config not found
Error: disk full
INFO done
l32% grep -ow 'disk' app.log
disk
Recursive search
grep -r PATTERN DIR descends into DIR and searches every file under it, printing path:line for each hit. Add -l and it prints only the names of files that contain a match, once each, which is usually what you want when hunting for "where is this setting defined?". -L lists the files that do *not* match. With -r you nearly always want -n too, so you can jump straight to the line.
l32% grep -rn TODO src
src/main.c:3:// TODO: handle errors
src/README:1:TODO list
src/lib/helpers.c:7:/* TODO */
l32% grep -rl TODO src
src/main.c
src/README
src/lib/helpers.c
Context lines
An error message is often meaningless without the lines around it. -A N prints N lines After each match, -B N prints N lines Before, and -C N prints both. grep -C2 'disk full' app.log shows the failure with two lines of context on each side, enough to see what led to it. Groups of context are separated with --.
Commands in this lesson
| Command | What it does |
|---|---|
grep -i PATTERN file | Case-insensitive search. |
grep -n PATTERN file | Show line numbers. |
grep -v PATTERN file | Lines that do not match. |
grep -c PATTERN file | Count matching lines. |
grep -w PATTERN file | Whole words only. |
grep -r PATTERN dir | Search every file under dir. |
grep -rl PATTERN dir | Only the names of files that match. |
grep -C 2 PATTERN file | Two lines of context around each match. |
Quiz
What does `grep -c error app.log` print?
- The matching lines with a counter
- Only the number of lines containing `error`
- The number of times `error` appears, counting repeats on a line
Which command shows config.txt without its comment lines (those starting with #)?
- `grep '#' config.txt`
- `grep -v '^#' config.txt`
- `grep -c '^#' config.txt`
You want the names of all files under src/ that mention `password`, each once. Which command?
- `grep -rl password src`
- `grep -rn password src`
- `grep -c password src/*`
What does `-w` change in `grep -w log file.txt`?
- It matches `log` only as a whole word, not inside `login` or `catalog`
- It writes the results to a file
- It ignores case
Which option shows two lines before and after each match?
- `-A 2`
- `-B 2`
- `-C 2`
Practice
In /root/lab/l32/app.log, find every line containing `error` in any capitalization, with line numbers, and save that output in /root/lab/l32/errors.txt.
Save into /root/lab/l32/clean.txt all the lines of /root/lab/l32/app.log that do NOT contain `DEBUG`.
Under /root/lab/l32/src there are source files at several depths. Write into /root/lab/l32/todo-files.txt the names of the files that contain `TODO`, one per line, with a single grep command.
Open this lesson in the app to do the tasks in a real Linux machine and have them checked.