1. Library
  2. Tools and Commands
  3. System Tools

Updated 10 hours ago

grep is how you interrogate your logs. You have thousands—maybe millions—of lines, and somewhere in there is the answer to why your service crashed at 3 AM. grep lets you ask questions, follow threads, and narrow in on what actually happened.

The Basic Question

The simplest question: does this pattern exist?

grep "error" /var/log/syslog

Every line containing "error" appears. But logs are messy—sometimes it's "Error", sometimes "ERROR". Ask the question without caring about case:

grep -i "error" /var/log/syslog

Now you're asking: "Show me every line that mentions error, however it's written."

Widening the Search

One file rarely tells the whole story. Search across all logs:

grep "error" /var/log/*

Each match shows which file it came from. Go deeper into subdirectories:

grep -r "error" /var/log/

Now you're asking the entire logging hierarchy the same question.

Filtering Out Noise

Some questions are better asked in reverse. Instead of "show me errors," ask "show me everything except debug noise":

grep -v "debug" /var/log/application.log

The -v flag inverts the match. Chain them to progressively filter:

grep -v "debug" /var/log/app.log | grep -v "info"

What remains is the signal without the noise.

Understanding Context

Finding an error is step one. Understanding it requires context—what happened before? What happened after?

grep -A 5 "error" /var/log/syslog    # 5 lines after
grep -B 5 "error" /var/log/syslog    # 5 lines before
grep -C 5 "error" /var/log/syslog    # 5 lines both directions

Cascading failures become visible. The error at line 1000 makes sense once you see what happened at line 995.

Counting Instead of Showing

Sometimes you don't need the lines—you need the pattern:

grep -c "error" /var/log/*.log

This shows error counts per file. Instantly reveals which service is screaming loudest.

Line Numbers

grep -n "error" /var/log/syslog

When you need to open the file and navigate directly to the problem, or reference specific entries in a report.

Regular Expressions: Precise Questions

Basic patterns ask basic questions. Regular expressions ask precise ones.

Lines that start with ERROR (not just contain it):

grep "^ERROR" /var/log/application.log

The caret anchors to line start.

Lines that end with a pattern:

grep "failed$" /var/log/syslog

The dollar sign anchors to line end.

Match any single character:

grep "err.r" /var/log/syslog

Matches "error", "err0r", "err r"—anything with one character in that position.

Extended Regex: Ask Multiple Questions at Once

Enable extended regex with -E for cleaner syntax:

grep -E "error|warning|critical" /var/log/syslog

The pipe means OR. One command asks three questions simultaneously.

Match IP address patterns:

grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" /var/log/syslog

Braces specify repetition counts. This matches IP-shaped strings.

Character Classes

Be specific about what characters you're looking for:

grep "[0-9]" /var/log/syslog              # Any digit
grep "[A-Z]" /var/log/syslog              # Any uppercase letter
grep "[^0-9]" /var/log/syslog             # Any non-digit

The caret inside brackets negates: "anything except these."

Whole Words Only

grep -w "error" /var/log/syslog

Matches "error" but not "errors", "errored", or "suberror". The -w flag demands word boundaries on both sides.

Extract Just the Match

The -o flag shows only what matched, not the entire line:

grep "Failed password" /var/log/auth.log | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"

This extracts just the IP addresses from failed login attempts. The full lines are noise—you want the list of attackers.

Searching Compressed Logs

Log rotation compresses old files. zgrep handles them transparently:

zgrep "error" /var/log/syslog.1.gz

Same syntax, automatic decompression.

Real Investigations

Find failed SSH attempts:

grep "Failed password" /var/log/auth.log

Find HTTP 500 errors in Apache:

grep "\" 500 " /var/log/apache2/access.log

The quotes and spaces ensure you match the status code field specifically.

Find errors from the current hour:

grep "$(date +%b' '%d' '%H)" /var/log/syslog | grep -i error

Match the timestamp format first, then filter for errors within that timeframe.

Building Analysis Pipelines

Count unique error types by frequency:

grep "ERROR" /var/log/app.log | cut -d':' -f2 | sort | uniq -c | sort -nr

grep finds the lines, cut extracts the error message, sort and uniq count duplicates, final sort ranks by frequency. The most common errors float to the top.

Monitor logs in real-time:

tail -f /var/log/syslog | grep --line-buffered "error"

The --line-buffered flag prevents grep from holding output—matches appear immediately.

Performance

For large files, fixed strings search faster than regex:

grep -F "exact.string.with.dots" /var/log/huge.log

The -F flag treats the pattern literally. No regex compilation overhead, no escaping needed for special characters.

For very large files, ripgrep (rg) provides the same syntax with significantly better performance.

Common Mistakes

Periods match any character in regex. Search for a literal IP:

grep "192\.168\.1\.1" /var/log/syslog

Without backslashes, 192.168.1.1 matches 192x168y1z1 too.

Quote patterns with spaces or special characters:

grep "error: connection failed" /var/log/syslog

The shell will mangle unquoted patterns.

Exit Codes for Scripts

grep returns 0 when it finds matches, 1 when it doesn't:

if grep -q "error" /var/log/syslog; then
    echo "Errors found!"
fi

The -q flag suppresses output—you just want the yes/no answer.

Frequently Asked Questions About Grep

Was this page helpful?

😔
🤨
😃