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.log

Use -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:

OptionDescription
-iIgnore case when matching.
-r, -RSearch recursively through directories.
-nShow the line number of each match.
-cCount matching lines instead of printing them.
-lPrint only the names of files that contain a match.
-vInvert — show lines that do NOT match.
-wMatch whole words only.
-oPrint only the matched part of the line.
-EExtended regex (enables +, ?, |, () without backslashes).
-FFixed strings — treat the pattern literally, not as a regex.
-A nPrint n lines of context after each match.
-B nPrint n lines of context before each match.
-C nPrint n lines of context around each match.
--color=autoHighlight 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.txt

grep 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 -u

The [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