Read

Module 4 · Finding things

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

OptionEffect
-iignore case: error matches Error and ERROR
-nprefix each line with its line number
-vinvert: print the lines that do NOT match
-cprint only the count of matching lines
-wmatch whole words only
-xmatch whole lines only
-oprint 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

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

CommandWhat it does
grep -i PATTERN fileCase-insensitive search.
grep -n PATTERN fileShow line numbers.
grep -v PATTERN fileLines that do not match.
grep -c PATTERN fileCount matching lines.
grep -w PATTERN fileWhole words only.
grep -r PATTERN dirSearch every file under dir.
grep -rl PATTERN dirOnly the names of files that match.
grep -C 2 PATTERN fileTwo lines of context around each match.

Quiz

  1. 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
  2. Which command shows config.txt without its comment lines (those starting with #)?

    • `grep '#' config.txt`
    • `grep -v '^#' config.txt`
    • `grep -c '^#' config.txt`
  3. 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/*`
  4. 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
  5. Which option shows two lines before and after each match?

    • `-A 2`
    • `-B 2`
    • `-C 2`

Practice

  1. 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.

  2. Save into /root/lab/l32/clean.txt all the lines of /root/lab/l32/app.log that do NOT contain `DEBUG`.

  3. 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.