grep Advanced

Basic grep is powerful. With regular expressions, it becomes unstoppable.

Context Lines

Sometimes you need the lines around a match:

Terminal
$# 3 lines before match:
$grep -B 3 'error' log.txt
(3 lines before + match)
$
$# 3 lines after match:
$grep -A 3 'error' log.txt
(match + 3 lines after)
$
$# 3 lines before AND after:
$grep -C 3 'error' log.txt
(3 before + match + 3 after)

Stack Traces

When debugging errors in logs, -C 5 or -A 10 often shows you the full stack trace.

Regular Expressions

Basic Regex with grep

Terminal
$grep '^error' log.txt
(lines starting with 'error')
$grep 'error$' log.txt
(lines ending with 'error')
$grep '^$' file.txt
(empty lines)

Anchors:

  • ^ = start of line
  • $ = end of line

Extended Regex with -E

For more regex features, use -E (or egrep):

Terminal
$grep -E 'error|warning|fatal' log.txt
(matches any of these words)
$grep -E '[0-9]{3}-[0-9]{4}' file.txt
(matches phone-like patterns: 123-4567)

Common Patterns

hljs bash
# IP addresses (rough match)
grep -E '[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+' log.txt

# Email addresses (rough match)
grep -E '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}' file.txt

# URLs
grep -E 'https?://[^ ]+' file.txt

Word Boundaries

-w matches whole words only:

Terminal
$grep 'port' config.txt
port=3000 report_enabled=true import_path=/data
$grep -w 'port' config.txt
port=3000

Without -w, "port" also matches "report" and "import."

Multiple Patterns

From File

Terminal
$cat patterns.txt
error warning fatal
$grep -f patterns.txt log.txt
(matches any pattern from file)

OR Patterns

Terminal
$grep -E 'GET|POST|PUT|DELETE' access.log
(all HTTP methods)

Only Print Match

By default, grep prints the whole line. Use -o to print only the match:

Terminal
$grep -o '[0-9]\+' file.txt
123 456 789

Great for extracting specific data.

Quiet Mode

-q returns only exit status, no output:

hljs bash
if grep -q 'error' log.txt; then
  echo "Errors found!"
fi

Exit codes:

  • 0 = match found
  • 1 = no match
  • 2 = error occurred

Color Output

Terminal
$grep --color=auto 'error' log.txt
(error highlighted)

Most systems have this aliased by default.

Excluding Files/Directories

When searching recursively:

Terminal
$grep -r --exclude='*.log' 'password' .
(skip log files)
$grep -r --exclude-dir=node_modules 'TODO' .
(skip node_modules)
$grep -r --include='*.js' 'function' .
(only search .js files)

For Large Projects

Always exclude node_modules, .git, vendor, etc. They make searches painfully slow.

Real-World Examples

Find Failed SSH Logins

Terminal
$grep -i 'failed\|invalid' /var/log/auth.log
(authentication failures)

Extract IP Addresses

Terminal
$grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' access.log | sort | uniq -c
45 192.168.1.1 23 10.0.0.5

Find TODO Comments

Terminal
$grep -rn --include='*.py' 'TODO\|FIXME\|XXX' .
(all todo comments in Python files)
Knowledge Check

How do you search for lines starting with 'Error' (at the beginning of the line)?

Quick Reference

FlagEffect
-EExtended regex
-wWhole word only
-oPrint only match
-qQuiet (exit code only)
-A nn lines after
-B nn lines before
-C nn lines context
--includeOnly search matching files
--exclude-dirSkip directories

Key Takeaways

  • Use -E for extended regex (OR patterns, quantifiers)
  • -w prevents partial word matches
  • -A, -B, -C show context around matches
  • -o extracts just the matching text
  • --exclude-dir skips directories like node_modules
  • ^ and $ anchor to start/end of line

Next: extracting columns with cut.