The grep command in Linux

grep searches text for lines matching a pattern and prints them. It is arguably the most useful text tool on any Unix system: you will use it to dig through logs, filter the output of other commands, and locate where something is defined in a codebase. The name comes from the old editor command g/re/p — "globally search a regular expression and print".

How grep works

grep streams input line by line, testing each against a compiled pattern and printing the survivors. The pattern is compiled once into a matching automaton before any data is read — the reason grep chews through gigabytes at hundreds of MB/s.

Its three dialects are really three engines. Basic regex (default) and extended regex (-E) differ mainly in which characters are special; -F disables regex entirely and uses fast literal-string search — the right choice when hunting for text full of dots and brackets. Two more internals worth knowing: locale affects both speed and matching (LC_ALL=C makes grep dramatically faster on ASCII logs), and a file containing NUL bytes flips grep into "binary file matches" mode unless you force -a.

Syntax

grep [OPTIONS] PATTERN [FILE...]

Common options

OptionWhat it does
-iIgnore case: "Error", "ERROR" and "error" all match.
-vInvert: print lines that do NOT match.
-nPrefix each matching line with its line number.
-rRecursive: search every file under a directory.
-lPrint only the names of files that contain a match.
-cPrint only the count of matching lines.
-wMatch whole words only: "log" will not match "login".
-A n / -B n / -C nShow n lines of context After, Before, or around (Center) each match.
-EExtended regular expressions (alternation with |, + and ? without escaping).

How to use grep: examples

$ grep error app.log

Print every line of app.log containing "error".

$ grep -i error app.log

Same, but case-insensitive — catches Error and ERROR too.

$ grep -rn "TODO" src/

Search recursively through a directory, showing file names and line numbers. The classic way to find every TODO in a project.

$ grep -v "^#" config.conf

Show a config file without its comment lines: -v inverts, and ^# matches lines starting with #.

$ ps aux | grep nginx

Filter the output of another command through a pipe — one of the most common grep patterns.

$ grep -c "GET" access.log

Count how many lines contain GET, without printing them.

$ grep -E "warn|error" app.log

Extended regex: match lines containing either word.

$ grep -B 2 -A 5 "Exception" app.log

Print each match with 2 lines before and 5 after — invaluable for reading stack traces in logs.

Real-world use cases for grep

Incident triage in logs

Production alarm at 3am: grep -i error /var/log/app/*.log finds the failures; add -B2 -A5 for context around each, and -c to gauge the scale. This sequence — match, context, count — is the universal first response to any log-based incident.

Auditing a codebase

Where is that setting used? grep -rn "MAX_RETRIES" src/ answers in milliseconds with file and line numbers. Before IDE indexing, and still today over SSH, recursive grep is how engineers navigate unfamiliar code.

Try grep yourself

This is a live sandbox with a small filesystem (documents/, notes.txt, backup.sh…). Nothing you do here can break anything — experiment freely. Try: grep -i bash notes.txt

Pro tips and common mistakes

Frequently asked questions about grep

How do I grep recursively through directories?

Use grep -r pattern directory/. Adding -n includes line numbers: grep -rn "TODO" src/ is the standard form.

How do I search for lines that do NOT contain a word?

Invert the match with -v: grep -v debug app.log prints every line that does not contain "debug".

What is the difference between grep, egrep and fgrep?

egrep is equivalent to grep -E (extended regex) and fgrep to grep -F (fixed strings, no regex). The standalone names are deprecated; use the flags instead.

Can grep search multiple patterns at once?

Yes: grep -E "one|two" file, or repeat -e: grep -e one -e two file.

How grep compares

sed vs awk

sed edits lines; awk understands columns. Substitution is sed, computation is awk.

grep vs ripgrep (rg)

grep is everywhere; ripgrep is dramatically faster on code and respects .gitignore by default.

Things people do with grep

Find and replace text in files

Replace text in one file or across a whole project, safely.

Search text inside files

Find which files contain a word, and exactly where.

Search recursively with grep

Search every file under a directory with grep, show filenames and line numbers, and skip noisy folders.

Search with grep ignoring case

Make grep match Error, ERROR and error with one option.

Search for multiple patterns with grep

Match several words with grep using -e or extended regular expressions.

Find files by name in Linux

Locate files and directories by exact name or wildcard pattern with find.

Search Bash command history

Find a command you ran before using history, reverse search and grep.

Count lines in a Linux file

Count lines, words and bytes with wc, with useful variations for logs and source files.

View the end of a file

Use tail to inspect recent log entries and control how many lines you see.

Watch a Linux log file in real time

Follow new log entries with tail and handle log rotation correctly.

Related commands

cat

Print file contents, number lines, and join multiple files together.

find

Locate files anywhere in a directory tree by name, type, size, date — and act on them.

Want to build real fluency? The interactive course takes you through grep and every other essential command with guided, checked exercises.