# grep — Search Text with Regular Expressions

> Search files and streams for text patterns with grep — BRE, ERE and PCRE regex, recursive search, context lines and precise output control.

Source: https://www.jpkc.com/db/en/cheatsheets/files-text/grep/

<!-- PROSE:intro -->
grep is the go-to tool for finding text. It scans files or piped input line by line and prints every line that matches a pattern – from a plain literal string to a full regular expression. You reach for it many times a day: hunting through log files, searching a code base, filtering the output of another command, or checking a condition inside a script via its exit code. This guide covers the flags that matter most – case-insensitive and whole-word matching, recursive search, the three regex flavours (`-E`, `-P`, `-F`), context lines and output control.
<!-- PROSE:intro:end -->

## Basic Search

`grep '<pattern>' <file>` — Search for a pattern in a file and print matching lines.

```bash
grep 'error' /var/log/syslog
```

`grep '<pattern>' <file1> <file2>` — Search for a pattern in multiple files.

```bash
grep 'TODO' app.js utils.js
```

`grep -r '<pattern>' <path>` — Search recursively through all files in a directory.

```bash
grep -r 'console.log' src/
```

`grep -R '<pattern>' <path>` — Search recursively and follow symbolic links.

```bash
grep -R 'import' /usr/local/lib/
```

`grep -i '<pattern>' <file>` — Case-insensitive search.

```bash
grep -i 'warning' /var/log/syslog
```

`grep -w '<pattern>' <file>` — Match whole words only (not substrings).

```bash
grep -w 'error' app.log
```

`grep -x '<pattern>' <file>` — Match entire lines only.

```bash
grep -x 'OK' status.txt
```

## Regular Expressions

`grep -E '<pattern>' <file>` — Use extended regular expressions (ERE) — supports +, ?, |, () without escaping.

```bash
grep -E 'error|warning|fatal' app.log
```

`grep -P '<pattern>' <file>` — Use Perl-compatible regular expressions (PCRE) — supports lookahead, lookbehind, \d, etc.

```bash
grep -P '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' access.log
```

`grep -F '<string>' <file>` — Treat the pattern as a fixed string, not a regex (faster for literal matches).

```bash
grep -F '$(document).ready' app.js
```

`grep -E '^<pattern>' <file>` — Match lines starting with a pattern.

```bash
grep -E '^#' config.ini
```

`grep -E '<pattern>$' <file>` — Match lines ending with a pattern.

```bash
grep -E '\.js$' filelist.txt
```

`grep -E '<a>|<b>' <file>` — Match lines containing either pattern (alternation).

```bash
grep -E 'GET|POST' access.log
```

`grep '\.<ext>' <file>` — Escape special regex characters with backslash for literal match.

```bash
grep 'version 2\.0' changelog.txt
```

## Output Control

`grep -n '<pattern>' <file>` — Show line numbers alongside matching lines.

```bash
grep -n 'function' app.js
```

`grep -c '<pattern>' <file>` — Count the number of matching lines.

```bash
grep -c 'ERROR' app.log
```

`grep -l '<pattern>' <files>` — Print only the filenames that contain a match.

```bash
grep -rl 'TODO' src/
```

`grep -L '<pattern>' <files>` — Print only the filenames that do not contain a match.

```bash
grep -rL 'use strict' src/*.js
```

`grep -o '<pattern>' <file>` — Print only the matched part of each line, not the entire line.

```bash
grep -oE '[0-9]+\.[0-9]+\.[0-9]+' version.txt
```

`grep -H '<pattern>' <file>` — Always print the filename with each match.

```bash
grep -Hn 'error' *.log
```

`grep -h '<pattern>' <files>` — Suppress filenames in output when searching multiple files.

```bash
grep -h 'export' src/*.js
```

`grep --color=always '<pattern>' <file>` — Highlight matches in color (useful when piping through less).

```bash
grep --color=always 'error' app.log | less -R
```

## Context Lines

`grep -A <n> '<pattern>' <file>` — Show n lines after each match.

```bash
grep -A 3 'Exception' error.log
```

`grep -B <n> '<pattern>' <file>` — Show n lines before each match.

```bash
grep -B 5 'FATAL' error.log
```

`grep -C <n> '<pattern>' <file>` — Show n lines before and after each match (context).

```bash
grep -C 2 'segfault' /var/log/kern.log
```

## Inverting & Filtering

`grep -v '<pattern>' <file>` — Invert match — print lines that do not match the pattern.

```bash
grep -v '^#' config.ini
```

`grep -v -e '<a>' -e '<b>' <file>` — Exclude lines matching any of several patterns.

```bash
grep -v -e '^#' -e '^$' config.ini
```

`grep -e '<a>' -e '<b>' <file>` — Match lines containing any of multiple patterns.

```bash
grep -e 'error' -e 'warning' app.log
```

`grep -f <patternfile> <file>` — Read patterns from a file (one pattern per line).

```bash
grep -f keywords.txt document.txt
```

## Recursive Options

`grep -r --include='<glob>' '<pattern>' <path>` — Search recursively but only in files matching a glob pattern.

```bash
grep -r --include='*.php' 'require_once' /var/www/
```

`grep -r --exclude='<glob>' '<pattern>' <path>` — Search recursively but skip files matching a glob pattern.

```bash
grep -r --exclude='*.min.js' 'function' src/
```

`grep -r --include='*.{js,ts}' '<pattern>' <path>` — Search recursively in multiple file types using brace expansion.

```bash
grep -r --include='*.{js,ts}' 'import' src/
```

`grep -r --exclude-dir='<dir>' '<pattern>' <path>` — Search recursively but skip specific directories.

```bash
grep -r --exclude-dir='node_modules' 'TODO' .
```

`grep -r --exclude-dir={<a>,<b>} '<pattern>' <path>` — Skip multiple directories during recursive search.

```bash
grep -r --exclude-dir={node_modules,.git,dist} 'console' .
```

## Binary & Special Files

`grep -a '<pattern>' <file>` — Treat binary files as text.

```bash
grep -a 'version' program.bin
```

`grep -I '<pattern>' <file>` — Skip binary files entirely (treat them as non-matching).

```bash
grep -rI 'config' /opt/
```

`grep -Z '<pattern>' <files>` — Output null byte after each filename (for use with xargs -0).

```bash
grep -rlZ 'TODO' src/ | xargs -0 sed -i 's/TODO/DONE/g'
```

## Piping & Combining

`<command> | grep '<pattern>'` — Filter the output of another command.

```bash
ps aux | grep 'nginx'
```

`<command> | grep -v 'grep'` — Filter output and exclude the grep process itself from results.

```bash
ps aux | grep 'nginx' | grep -v 'grep'
```

`<command> | grep -c '<pattern>'` — Count matching lines from piped input.

```bash
cat access.log | grep -c '404'
```

`grep '<a>' <file> | grep '<b>'` — Chain grep commands to match lines containing both patterns (AND logic).

```bash
grep 'ERROR' app.log | grep 'database'
```

`<command> | grep -q '<pattern>' && echo 'found'` — Quiet mode — suppress output and use exit code in scripts.

```bash
grep -q 'root' /etc/passwd && echo 'root user exists'
```

## Practical Examples

`grep -rn 'TODO\|FIXME\|HACK' src/` — Find all TODO, FIXME and HACK comments in source code with line numbers.

`grep -rl 'old_function' src/ | xargs sed -i 's/old_function/new_function/g'` — Find and replace a string across all matching files.

`grep -oP '(?<=href=")[^"]+' index.html` — Extract all URLs from href attributes using PCRE lookbehind.

`grep -E '^[0-9]{1,3}(\.[0-9]{1,3}){3}' access.log | sort | uniq -c | sort -rn | head` — Count and rank IP addresses in a log file.

`grep -Pzo '(?s)<div class="content">.*?</div>' page.html` — Match a multiline pattern using PCRE with null-terminated output.

`grep -r --include='*.env' -l 'PASSWORD' .` — Find environment files that contain password references.

`grep -cE '^(import|from)' src/*.py | sort -t: -k2 -rn` — Count import statements per Python file, sorted by count.

`grep -B2 -A5 'function.*login' auth.js` — Show context around a function definition.

`zgrep '<pattern>' <file.gz>` — Search inside gzip-compressed files without decompressing.

```bash
zgrep 'error' /var/log/syslog.2.gz
```

`grep -rn --include='*.{css,scss}' 'z-index' src/` — Find all z-index declarations across CSS and SCSS files.

<!-- PROSE:outro -->
## Conclusion

grep earns its place in your daily workflow by being fast, composable and predictable: pick the right regex flavour (`-F` for literals, `-E` for extended, `-P` for Perl features), add `-r` to walk directories, and combine `-n`, `-o` or `-c` to shape the output. grep itself only reads – it never changes your files – so the real care lies in what you pipe its results into, for example `grep -rlZ … | xargs -0 sed -i …`, which edits files in place. Note that `-P` (PCRE) is a GNU extension and is not available in the BSD/macOS grep; there you install GNU grep (as `ggrep`) or fall back to `-E`.

## Further Reading

- [GNU grep manual](https://www.gnu.org/software/grep/manual/grep.html) – complete reference for options and regex syntax
- [Regular-Expressions.info](https://www.regular-expressions.info/) – in-depth tutorial on regex, including PCRE features
<!-- PROSE:outro:end -->

## Related Commands

- [sed](https://www.jpkc.com/db/en/cheatsheets/files-text/sed/) – stream editor for transforming the lines grep finds
- [awk](https://www.jpkc.com/db/en/cheatsheets/files-text/awk/) – field-aware processing and reporting on matched lines
- [find](https://www.jpkc.com/db/en/cheatsheets/files-text/find/) – locate files by name and metadata, then hand them to grep

