Quick take: The grep command searches text for lines matching a pattern. Use -i to ignore case, -r to search directories recursively, -n to show line numbers, and -E for extended regular expressions.
Introduction
The grep command (global regular expression print) searches files or input for lines that match a pattern and prints them. It is the workhorse of text searching in Linux — finding a setting in a config file, a message in a log, or every occurrence of a function across a codebase.
This guide covers everyday grep usage, the options you will use most, and how regular expressions unlock far more powerful searches.
Syntax
The basic syntax of the grep command is:
grep [OPTIONS] PATTERN [FILE...]Using grep with Regular Expressions
grep's real power is regular expressions. With basic regex you can anchor matches and use character classes; with -E (extended regex) you get alternation and quantifiers without backslashes.
# Lines starting with 'ERROR'
grep '^ERROR' app.log
# Lines ending with a semicolon
grep ';$' code.c
# IP-like pattern (extended regex)
grep -E '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' access.logUse -o to print only the matched portion, which is perfect for extracting values rather than whole lines.
Common Options and Parameters
The most useful options and parameters for the grep command:
| Option | Description |
|---|---|
| -i | Ignore case when matching. |
| -r, -R | Search recursively through directories. |
| -n | Show the line number of each match. |
| -c | Count matching lines instead of printing them. |
| -l | Print only the names of files that contain a match. |
| -v | Invert — show lines that do NOT match. |
| -w | Match whole words only. |
| -o | Print only the matched part of the line. |
| -E | Extended regex (enables +, ?, |, () without backslashes). |
| -F | Fixed strings — treat the pattern literally, not as a regex. |
| -A n | Print n lines of context after each match. |
| -B n | Print n lines of context before each match. |
| -C n | Print n lines of context around each match. |
| --color=auto | Highlight the matched text. |
Practical Examples
Real grep commands you can run today:
# Search for a word in a file
grep 'error' app.log
# Case-insensitive search
grep -i 'warning' app.log
# Recursive search through a directory
grep -rn 'TODO' ./src
# Show only matching file names
grep -rl 'api_key' /etc
# Count how many lines match
grep -c 'GET' access.log
# Invert: lines that do NOT contain '#'
grep -v '^#' config.conf
# Show 3 lines of context around matches
grep -C 3 'panic' kernel.log
# Extended regex: match foo or bar
grep -E 'foo|bar' data.txtgrep in Pipelines and Real Workflows
grep is most powerful as a filter in a pipeline, narrowing the output of other commands. This is how administrators find a process, a port, or a setting buried in noisy output.
# Is nginx running?
ps aux | grep [n]ginx
# Which package owns a command (Debian/Ubuntu)
dpkg -l | grep openssh
# Count 404s in a web log
grep -c ' 404 ' access.log
# Show unique IP addresses that hit an endpoint
grep '/login' access.log | awk '{print $1}' | sort -uThe [n]ginx trick is worth knowing: the bracket stops grep from matching its own process line, a classic annoyance when grepping ps output.
Common grep Mistakes
The most frequent confusion is regex versus literal text. By default grep treats the pattern as a basic regular expression, so characters like ., *, and [ are special. If you are searching for a literal string that contains them — an IP address or a file path — use -F (fixed strings) so they are matched verbatim.
A second mistake is forgetting to quote the pattern. Without quotes the shell may expand * or ? before grep ever sees them. Always wrap patterns in single quotes, and remember that -w (whole word) prevents partial matches like cat inside concatenate.
Tips and Best Practices
- Combine flags:
grep -rin 'pattern' .searches recursively, case-insensitively, with line numbers — the search you will run most. - Use
-F(fixed strings) when your search text contains regex characters like.or*that you want treated literally. - Pipe other commands into grep to filter their output, e.g.
ps aux | grep nginx.
Final Thoughts
grep is the first tool to reach for whenever you need to find text. Learn the core flags — -i, -r, -n, -v, -c — and a little regular-expression syntax, and you can search any file, log, or codebase in seconds. It pairs naturally with pipes, find, and sed.
FAQ: grep Command in Linux
How do I search for text in a file with grep?+
Run grep 'pattern' filename. Add -i to ignore case and -n to show line numbers. For a directory, add -r to search recursively.
How do I search recursively through directories?+
Use grep -r 'pattern' /path, or grep -rn to include line numbers and grep -rl to list only the matching file names.
How do I show lines that do NOT match?+
Use the -v flag: grep -v 'pattern' file prints every line except those containing the pattern. It is great for stripping comments with grep -v '^#'.
How do I match whole words only?+
Use -w: grep -w 'cat' file matches the word cat but not 'category' or 'concatenate'.
What is the difference between grep, egrep, and grep -E?+
egrep is the old name for extended-regex grep and is now deprecated in favour of grep -E, which enables +, ?, |, and () without backslashes. They behave the same; prefer grep -E.
Need help with Linux servers or infrastructure?
Work directly with Muhammad Irfan Aslam for Linux, Ubuntu, Docker, DevOps, cloud, CI/CD, or infrastructure support.
Hire Me for Support