The terminal's regex tool
For shell-level text searching, the canonical tool was grep. The modern replacement is ripgrep (rg) — written in Rust, uses RE2-class engine, recursive by default, respects .gitignore, blazing fast.
grep flavors
POSIX grep has three modes that differ in how they treat metacharacters:
- BRE (default):
?,+,{},(),|are LITERAL unless escaped.grep 'foo\(bar\)' - ERE (
grep -Eoregrep): Modern syntax — those metacharacters work without escaping.grep -E 'foo(bar)' - PCRE (
grep -P): Full Perl-compatible. Lookaround, backreferences, named groups. Not always available (depends on grep build).
Use -E by default. Use -P when you need PCRE features. Avoid plain grep with regex — too many gotchas.
ripgrep — the modern default
rg uses RE2-style syntax (no lookaround, no backreferences, but linear time). It's recursive by default, respects .gitignore, supports Unicode well, and is dramatically faster than grep on large codebases.
Common flags:
rg pattern— search recursively in current directoryrg -i pattern— case-insensitiverg -n pattern— show line numbers (default in interactive mode)rg -l pattern— list only filenames with matchesrg -A 3 pattern— show 3 lines of context after each matchrg --pcre2 pattern— enable PCRE2 (lookaround, backreferences)rg -r 'replacement' pattern— preview replacements ($1,$2for groups)