grep Command in Linux: Search Text, Logs, and Command Output

grep prints lines that match a pattern in files or piped input. Use it to scan logs, filter command output, and count or list matches with GNU grep options.

Published

Updated

Read time 8 min read

Reviewed byDeepak Prasad

grep Command in Linux: Search Text, Logs, and Command Output
About grep prints lines that match a pattern in files or piped input. Use it to scan logs, filter command output, and count or list matches with GNU grep options.
Tested on Ubuntu 25.04 (Plucky Puffin); grep (GNU) 3.11; kernel 7.0.0-27-generic
Package grep
Man page grep(1)
Privilege user (read access to files)
Distros

GNU grep on Linux (Ubuntu, Debian, RHEL, Fedora, SUSE, Arch, and others).

BSD/macOS grep differs slightly — test flags on the target host for portable scripts.

Related guide

grep — quick reference

Pattern matching

Control how grep interprets the search text.

When to use Command
Search for a literal string in one file grep 'ERROR' app.log
Case-insensitive match grep -i error app.log
Match whole words only grep -w log words.txt
Extended regex (alternation, grouping) grep -E 'error|warning' app.log
Fixed string — no regex metacharacters grep -F 'rate.limit' app.log
Multiple patterns in one run grep -e error -e warning app.log
Patterns listed in a file grep -f patterns.txt app.log

Output control

Shape what grep prints.

When to use Command
Show line numbers grep -n error app.log
Count matching lines grep -c error app.log
Print only the matched text grep -o '[0-9]+' file.txt
Invert — lines that do not match grep -v debug app.log
Stop after N matches grep -m 5 error app.log
Quiet — exit status only grep -q error app.log
Suppress "No such file" errors grep -s error missing.log

Files and directories

Search one file or several named files. For full directory trees, see the grep recursive.

When to use Command
Search several files in one run grep error file1.log file2.log
Walk a directory tree (-r, --include, --exclude-dir) grep recursive search

Context lines

Show surrounding log lines for debugging.

When to use Command
Lines after each match grep -A 2 error app.log
Lines before each match grep -B 2 error app.log
Lines before and after grep -C 2 error app.log

grep — command syntax

Synopsis from grep --help on Ubuntu 25.04 (GNU grep 3.11):

text
Usage: grep [OPTION]... PATTERNS [FILE]...
Search for PATTERNS in each FILE.
Example: grep -i 'hello world' menu.h main.c

Pattern selection and interpretation:
  -E, --extended-regexp     PATTERNS are extended regular expressions
  -F, --fixed-strings       PATTERNS are strings
  -e, --regexp=PATTERNS     use PATTERNS for matching
  -f, --file=FILE           take PATTERNS from FILE
  -i, --ignore-case         ignore case distinctions
  -w, --word-regexp         match only whole words

Output control:
  -n, --line-number         print line number with output lines
  -c, --count               print only a count of matching lines
  -l, --files-with-matches  print only names of FILEs with matches
  -r, --recursive           search directories recursively

With no FILE, grep reads standard input — the usual pattern in pipelines.


grep — command examples

Essential Case-insensitive search with -i

Log levels are not always capitalized the same way. -i matches every case variant.

Run the command:

bash
grep -i error app.log

Sample output:

text
2026-07-01 ERROR connection failed

Add -c when you only need a count: grep -ci error app.log prints 1 on this sample file.

Essential Filter command output through grep

Pipes send another command's stdout into grep — no temporary file required.

The same pattern works for ps aux | grep when hunting a PID; see the ps command for process columns before you filter.

Run the command:

bash
echo -e 'alpha\nbeta\ngamma' | grep beta

Sample output:

text
beta

The same pattern works on real tools: journalctl -u nginx | grep -i error or ps aux | grep '[n]ginx' (brackets avoid matching the grep process itself).

Common Line numbers (-n) and match count (-c)

Line numbers help you jump to the spot in an editor; counts summarize how noisy a log is.

Run the commands:

bash
grep -ni error app.log
grep -ci error app.log

Sample output:

text
2:2026-07-01 ERROR connection failed
1

Use -n during incident triage and -c in monitoring scripts that only need above-zero checks.

Common Show lines that do not match (-v)

Filtering out noise — debug lines, health checks — is often easier than listing what you want.

Run the command:

bash
grep -v -i debug app.log

Sample output:

text
2026-07-01 INFO service started
2026-07-01 ERROR connection failed

Combine with pipes: apt list --installed 2>/dev/null | grep -v automatic to hide auto-installed packages.

Common Multiple patterns with -E

Extended regex lets you alternate patterns with | without running grep twice.

Run the command:

bash
grep -Ei 'error|warning' app.log

Sample output:

text
2026-07-01 ERROR connection failed

For fixed strings with special characters, prefer -F or grep -F 'rate.limit' so dots are not regex wildcards.

Common List only filenames that match (-l)

When you care which file failed, not every matching line, -l prints filenames once.

Run the command:

bash
cp app.log server.log
echo 'no issues here' > clean.log
grep -li error *.log

Sample output:

text
app.log
server.log

Pair with xargs for batch fixes: grep -l error *.log | xargs sed -i 's/ERROR/INFO/'.

Common Context after a match (-A)

Stack traces and multi-line errors make more sense with the lines that follow the match.

Run the command:

bash
grep -A1 -i error app.log

Sample output:

text
2026-07-01 ERROR connection failed
2026-07-01 DEBUG cache hit

Use -B for lines before the match and -C N for both sides — common when reading application stack dumps.

Advanced Whole-word match with -w

Without -w, searching for log also hits login and catalog.

Run the command:

bash
echo 'log login logout' > words.txt
grep -w log words.txt

Sample output:

text
log login logout

Only the standalone word log matches; login and logout are skipped because -w requires word boundaries.

Advanced Script check with -q (exit status only)

Scripts often only need to know whether a pattern exists — -q prints nothing and sets exit code 0 or 1.

Run the command:

bash
grep -qi error app.log
echo "exit: $?"
grep -qi nomatch app.log
echo "exit: $?"

Sample output:

text
exit: 0
exit: 1

Use if grep -q pattern file; then … fi in shell conditionals. Combine with set -o pipefail when grep is in a pipeline that must signal failure.


grep — when to use / when not

Use grep when Use something else when
  • You need lines that contain (or exclude) a text pattern
  • You are searching logs, config files, or piped command output
  • You want quick counts, filenames, or line numbers
  • A regex line filter is enough — no column arithmetic
  • You need column/field processing → awk
  • You are finding files by name or size first → find, then grep the results
  • You need structured JSON querying → jq
  • Very large binary-aware search at scale → rg (ripgrep) if installed

grep vs awk

grep awk
Job Filter lines by pattern Parse fields and compute on rows
Output Matching lines (or counts/names) Custom columns, sums, reports
Regex Line-level Field- and record-level
Best for "Does this log line mention error?" "Print the fifth column when column 3 > 100"

Many pipelines chain them: grep error app.log | awk '{print $1,$4}'.


Command One line
grep Line-oriented pattern search (this page)

Browse the full index in our Linux commands reference.


grep — interview corner

What does grep do?

grep reads input line by line and prints lines where the pattern matches. The name comes from ed's g/re/p — global regular expression print.

bash
grep root /etc/passwd | head -1

Sample output:

text
root:x:0:0:root:/root:/bin/bash

A strong answer is:

"grep filters lines by pattern in files or stdin — I use it for logs, configs, and piped command output."

What is the difference between grep -E and egrep?

On modern GNU systems, egrep is grep -E — extended regular expressions with |, +, and groups without extra backslashes.

A strong answer is:

"grep -E enables extended regex; egrep is the same thing on GNU grep — I prefer grep -E for portability in scripts."

How do you search every file under a directory?

Use -r (or --recursive). For include/exclude globs, filename lists, and symlink behavior, see the grep recursive.

bash
grep -r -i error /var/log --include='*.log' 2>/dev/null | head

A strong answer is:

"grep -r pattern dir — I use the recursive cheat sheet for --include, --exclude-dir, and -l across trees."

What exit codes does grep return?

0 when a match is found, 1 when no match, 2 on errors (missing file, invalid regex). Scripts use -q to test presence silently.

A strong answer is:

"Exit 0 means match found, 1 means none, 2 means error — I use grep -q in conditionals and check PIPESTATUS in pipelines."

Why does grep highlight matches on Ubuntu?

Many distros alias grep to grep --color=auto. In scripts, call /usr/bin/grep or grep --color=never when escape codes would break parsing.

A strong answer is:

"Desktop Ubuntu often colorizes via alias — for scripts I use command grep or \grep to avoid ANSI codes in captured output."


Troubleshooting

Symptom Likely cause Fix
No output but you expected matches Case sensitivity or wrong pattern Try -i; test with grep -E and simpler pattern
grep: … No such file or directory Typo or missing path Check path; use -s to hide errors in loops
Matches login when you wanted log Substring match Add -w for whole words
Binary file matches Binary file without -a Use grep -a or skip binaries with --binary-files=without-match
Slow on huge trees Searching everything --include, --exclude-dir, or dedicated tools like ripgrep
Special characters behave oddly Regex metacharacters Use -F for fixed strings or escape metacharacters

Rohan Timalsina

is a technical writer and Linux enthusiast who writes practical guides on Linux commands and system administration. He focuses on simplifying complex topics through clear explanations.