grep -P, ripgrep and smarter searching

grep, sed & awk · Advanced · 10 min

Some extractions need lookarounds, and in big codebases a tool that respects .gitignore is dramatically faster.

GNU grep's -P switches to Perl-compatible regular expressions (PCRE2). That adds:

  • shorthand classes \d, \w, \s, and \b word boundaries;
  • lazy quantifiers like .*?;
  • lookarounds: (?<=user=)\w+ matches the name after user= without including the prefix;
  • \K, which drops everything matched so far from the reported match: grep -oP 'id=\K\d+' prints just the number.

-P is a GNU feature and may be missing in minimal builds; BSD and macOS grep don't support it. In portable scripts, prefer -E plus sed or awk for extraction.

For searching source trees, two other tools are often better than grep -r:

  • git grep searches only tracked files of a Git repository, very quickly, and can search other revisions: git grep TODO v1.0.
  • ripgrep (rg) recurses by default, skips files ignored by .gitignore, hidden files and binaries, uses all CPU cores and has a regex engine with guaranteed linear-time matching. Its flags mirror grep's (-i, -w, -l, -C) and -t py filters by file type.

Keep plain grep for pipelines and for scripts that must run everywhere; use rg or git grep interactively in large repositories.

Example

printf 'user=ana id=17\nuser=bo id=204\n' > log.txt

grep -oP 'id=\K\d+' log.txt                 # 17 / 204
grep -oP '(?<=user=)\w+' log.txt            # ana / bo
grep -oP 'user=.*?(?= )' log.txt            # user=ana / user=bo  (lazy + lookahead)

# portable equivalent without -P
grep -oE 'id=[0-9]+' log.txt | cut -d= -f2   # 17 / 204

# in a Git repository:
#   git grep -n 'TODO'            tracked files only
#   rg -t py 'def main'           ripgrep: respects .gitignore, parallel

Remember

  • grep -P adds \d, lazy quantifiers, lookarounds and \K
  • -P is GNU-only: use -E with cut or sed in portable scripts
  • git grep and ripgrep are faster for code search and skip ignored files

Watch out for

  • Shipping a script that uses grep -P to macOS users, where it fails with an invalid option error.

Check yourself

  1. What does grep -oP 'v=\K\d+' print for the line 'v=42;'?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.gnu.org/software/grep/manual/grep.html#grep-Programs