====== grep and ripgrep ======
===== Mode flags: what the pattern means =====
grep 'foo' f # BRE: + ? ( ) | need backslashes
grep -E 'a|b' f # ERE: modern syntax, no backslashes
grep -F 'a.b' f # literal string: dots are dots
grep -P '\d+' f # PCRE (Perl regex): \d \w lookahead etc.
rg 'pattern' # Rust regex: PCRE-like minus backrefs/lookaround
See [[terminal:scripting:regex|regex]] for the flavor differences.
===== Search control =====
grep -i 'error' # case-insensitive
grep -v 'debug' # invert: non-matching lines
grep -w 'port' # whole word only
grep -x 'exact line' # whole line only
grep -q pat f && echo yes # quiet: just the exit code
grep -c pat f # count matching LINES (not matches)
===== Output shaping =====
grep -n pat f # line numbers
grep -H pat * # always show filename
grep -o 'pat[^ ]*' f # print only the matched part
grep -m 5 pat f # stop after 5 matches
grep -A3 -B2 -C1 pat # after / before / context lines
grep --color=always # keep colors when piping
===== Recursive =====
grep -r pat dir/ # all files under dir
grep -rl pat dir/ # filenames only: good for find-replace
grep -r --include='*.conf' pat /etc
grep -r --exclude-dir={.git,node_modules} pat .
''rg'' does all this by default and respects .gitignore:
rg pat # recursive, numbers, colors
rg -l pat # files only
rg --type py pat # by file type; rg --type-list
rg -g '*.conf' pat # glob filter
rg -tmd -g '*.md' pat # markdown files only
rg --hidden pat # include dotfiles (still skips .gitignore'd)
rg -uuu pat # nothing ignored (careful)
===== Exit codes: scripting =====
if grep -q pat file; then ... # 0 found, 1 not found, 2 error
grep -q pat file || handle_missing
''grep -c'' prints ''0'' AND exits 1: don't rely on the count alone.
===== Fixed strings & special chars =====
grep -F 'a[b]c' f # literal brackets
grep -e '-pattern' f # pattern starting with dash
grep -f patterns.txt f # patterns from a file (OR'd)
===== Patterns that earn their keep =====
grep -vE '^\s*(#|$)' f # no comments/blanks
grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' # IPs
grep -E '^(ERROR|WARN)' log # tagged lines
grep -zoE 'start.*end' f # across newlines (GNU -z)
ls | grep -v '\.md$' # non-md files
===== Gotchas =====
* ''grep 'a*''' matches everything (''a*'' means zero or more ''a''): for a literal asterisk use ''grep 'a\*''' or ''grep -F 'a*'''.
* Binary files: ''grep'' says "Binary file matches": force text with ''-a'' or
suppress with ''-I''.
* ''zgrep''/''bzgrep''/''xzgrep'' for compressed files.
* ''grep'' returns per LINE: for "files containing X that also lack Y":
''comm -23 <(grep -l X *) <(grep -l Y *)''.
===== See Also =====
* [[terminal:scripting:start|Scripting Index]]
* [[terminal:tools:start|CLI Tools]]
* [[terminal:start|Return to terminal]]
* [[start|Return to wiki home]]