====== 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]]