32blogby StudioMitsu

grep Complete Guide: From Basics to ripgrep

Master grep regex patterns and real-world usage, then level up with ripgrep. Practical examples for log analysis and code search.

8 min read
grepripgrepCLILinuxbashRust
On this page

"I need to pull only errors from a log file." "I want to find every occurrence of a function across the entire codebase." "I want to see only the active lines in a config file, without comments."

These are the moments when grep steps in. And its evolution, the Rust-powered ripgrep, takes things even further.

This article walks you through grep basics, real-world patterns, and how ripgrep can supercharge your workflow.

What is grep?

grep stands for Global Regular Expression Print. It is a filter command that extracts lines matching a regular expression from text — one of the most fundamental tools in the Unix/Linux world.

Key characteristics:

  • Pipeline workhorse — designed to be chained with other commands via |
  • Pre-installed on virtually every Linux system — ready to use on any server
  • Flexible regex searching — from simple strings to complex patterns
  • Lightweight and fast — handles massive log files without breaking a sweat

The name originates from the ed editor command g/re/p (global / regular expression / print), written by Ken Thompson in 1973. It has been in active use for over 50 years.

Basic usage

Let's start with the essential grep options. These alone will cover the vast majority of your day-to-day search tasks.

bash
grep "error" logfile.txt

Every line containing "error" in the file is printed to stdout.

Commonly used options

bash
# Case-insensitive search
grep -i "error" logfile.txt

# Show line numbers
grep -n "error" logfile.txt

# Recursive search through directories
grep -rn "TODO" src/

# Show lines that do NOT match (exclusion filter)
grep -v "debug" logfile.txt

# Count matching lines
grep -c "error" logfile.txt

# Show only filenames that contain a match
grep -l "error" *.log

Context display

When you want to see surrounding lines, use -A (After), -B (Before), or -C (Context).

bash
# Show 3 lines after and 1 line before each match
grep -A 3 -B 1 "error" logfile.txt

# Show 3 lines of context on both sides (same as -A 3 -B 3)
grep -C 3 "error" logfile.txt

Multiple patterns

bash
# OR search (extended regex)
grep -E "error|warning|fatal" logfile.txt

# Fixed-string search (disables regex interpretation)
grep -F "console.log(" src/app.js

Regex patterns

The real power of grep lies in regular expressions. There are two flavors: Basic Regular Expressions (BRE) and Extended Regular Expressions (ERE, enabled with -E).

Common pattern reference

PatternMeaningExample
^patternStart of linegrep "^#" config.txt
pattern$End of linegrep "\.js$" files.txt
.Any single charactergrep "h.t" words.txt
[abc]Character classgrep "[0-9]" data.txt
[^abc]Negated character classgrep "[^aeiou]" words.txt
*Zero or more of precedinggrep "ab*c" data.txt
+ (ERE)One or more of precedinggrep -E "[0-9]+" data.txt
? (ERE)Zero or one of precedinggrep -E "colou?r" text.txt
\bWord boundarygrep -w "error" log.txt
{n,m} (ERE)Between n and m timesgrep -E "[0-9]{2,4}" data.txt

BRE vs ERE

In Basic Regular Expressions (BRE), metacharacters like +, ?, {}, |, and () require a backslash. Extended Regular Expressions (ERE, via -E) let you use them directly.

bash
# BRE: backslash required
grep "error\|warning" logfile.txt
grep "ab\{2,4\}" data.txt

# ERE: cleaner syntax (preferred)
grep -E "error|warning" logfile.txt
grep -E "ab{2,4}" data.txt

PCRE (Perl-Compatible Regular Expressions)

The -P flag enables Perl-compatible regex, unlocking shortcuts like \d (digit), \s (whitespace), and lookahead/lookbehind assertions.

bash
# Match a postal code pattern (3 digits, hyphen, 4 digits)
grep -P "\d{3}-\d{4}" addresses.txt

# Extract email-like strings
grep -oP "[\w.+-]+@[\w-]+\.[\w.]+" contacts.txt

Real-world use cases

Log file analysis

This is the most common use case in server operations.

bash
# Extract errors from a specific date (timestamped logs)
grep "2026-03-08.*ERROR" /var/log/app.log

# Extract IP addresses only
grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" access.log

# Tally HTTP status codes (grep + awk + sort combo)
grep -oE "HTTP/[0-9.]+ [0-9]+" access.log | awk '{print $2}' | sort | uniq -c | sort -rn
bash
# Find all TODO/FIXME comments across the project
grep -rn "TODO\|FIXME" --include="*.ts" src/

# Locate specific function calls
grep -rn "useState(" --include="*.tsx" src/

# Search import statements
grep -rn "^import.*from" --include="*.ts" --include="*.tsx" src/

Config file filtering

bash
# Strip comments and blank lines to show only active settings
grep -v "^#" /etc/ssh/sshd_config | grep -v "^$"

# Extract a specific section
grep -A 10 "\[database\]" config.ini

Pipeline combinations

grep shines brightest when combined with other commands.

bash
# Check running nginx processes (excludes the grep process itself)
ps aux | grep "[n]ginx"

# Search command history for git-related commands
history | grep "git"

# Extract errors from kernel messages
dmesg | grep -i "error"

# Filter a file listing by extension
find . -type f | grep "\.mdx$"

ripgrep: The modern alternative

ripgrep (command: rg) is a grep replacement written in Rust by Andrew Gallant. It has become the default search tool for many developers.

Key advantages:

  • Blazing speed — multi-threaded parallel search
  • Automatic .gitignore respect — skips node_modules, dist, etc. by default
  • Full Unicode support — handles CJK characters without issues
  • Automatic binary file skipping — ignores images and compiled files
  • Recursive by default — no need for -r

Installation

powershell
winget install BurntSushi.ripgrep.MSVC

Basic usage

bash
# Recursive search from the current directory (no -r needed)
rg "TODO"

# Search by file type
rg "TODO" --type js
rg "TODO" -t py

# Use glob patterns to narrow the search scope
rg "TODO" -g "*.tsx"

# Fixed-string search (disables regex)
rg -F "console.log("

# Case-insensitive search
rg -i "error"

# Line numbers are always shown by default
rg "error" src/

Advanced features

bash
# JSON output (useful for tool integration)
rg "error" --json

# Replacement preview (does NOT modify files)
rg "old_func" -r "new_func"

# Print only the matched portion (like grep -o)
rg -o "\d{3}-\d{4}" addresses.txt

# Include hidden files in the search
rg --hidden "SECRET_KEY"

# Ignore .gitignore and search all files
rg --no-ignore "password"

.rgignore for custom exclusions

Place an .rgignore file at the project root to define ripgrep-specific exclusions. The syntax is identical to .gitignore.

text
# .rgignore
dist/
coverage/
*.min.js
*.map

grep vs ripgrep

With both tools understood, here is a side-by-side comparison to guide your decision.

Featuregrepripgrep
Speed (large repos)Single-threadedMulti-threaded, fast
.gitignoreIgnores itRespects automatically
UnicodeLimitedFull support
Recursive by defaultRequires -rRecursive by default
Binary filesNeeds explicit optionsAuto-skipped
DependenciesNone (pre-installed)Separate install required
PCRE support-P flag--pcre2 flag
Color output--color=autoColored by default

When to use which:

  • On servers — grep is the only option. No extra installation needed.
  • On your dev machine — ripgrep is overwhelmingly more comfortable. Install it.
  • In shell scripts — use grep for portability. Use rg if the script runs only in your own environment.

Knowing both means you are never stuck. Master grep for the fundamentals, then add ripgrep for productivity.

Wrapping Up

grep is the bedrock of text searching, and it is unavoidable if you work with Linux. Combined with regular expressions, it handles log analysis, code search, and config filtering with ease.

ripgrep builds on that foundation, adding significant speed and convenience. Once you experience automatic .gitignore respect and multi-threaded search, there is no going back.

As a next step, explore text transformation with sed and awk, or try combining ripgrep with fzf for interactive search. Pairing search with transformation dramatically boosts your CLI productivity.

Related articles: