folk.zone Wiki

a public knowledge base

Site Tools


terminal:scripting:grep

This is an old revision of the document!


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 regex.md 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/grep.1792792853.txt.gz · Last modified: by 127.0.0.1