Grep - Text Search
Grep is a powerful tool for searching text patterns in files. This guide covers how to use grep (and its equivalents) across PowerShell, Mac, and Linux.
Search Text Inside a File
Linux/Mac
bash
# Basic search (case-sensitive)
grep "pattern" file.txt
# Case-insensitive search (recommended)
grep -i "pattern" file.txt
# Show line numbers
grep -n -i "pattern" file.txt
# Show lines before and after match
grep -C 3 -i "pattern" file.txt # 3 lines before and after
grep -B 2 -i "pattern" file.txt # 2 lines before
grep -A 2 -i "pattern" file.txt # 2 lines after
# Count matches
grep -c -i "pattern" file.txt
# Show only matching part
grep -o -i "pattern" file.txt
# Invert match (lines that don't match)
grep -v -i "pattern" file.txt
# Multiple patterns
grep -i -e "pattern1" -e "pattern2" file.txtPowerShell
powershell
# Basic search (case-insensitive by default)
Select-String -Path "file.txt" -Pattern "pattern"
# Case-sensitive search
Select-String -Path "file.txt" -Pattern "pattern" -CaseSensitive
# Show line numbers (included by default)
Select-String -Path "file.txt" -Pattern "pattern"
# Show context lines
Select-String -Path "file.txt" -Pattern "pattern" -Context 2,3 # 2 before, 3 after
# Count matches
(Select-String -Path "file.txt" -Pattern "pattern").Count
# Multiple patterns
Select-String -Path "file.txt" -Pattern "pattern1|pattern2"
# Get only the matching text
Select-String -Path "file.txt" -Pattern "pattern" | ForEach-Object { $_.Matches.Value }Find Files Containing Text
Linux/Mac
bash
# Search in current directory
grep -i "pattern" *
# Search recursively in all files
grep -r -i "pattern" .
# Search recursively with line numbers
grep -r -n -i "pattern" .
# Search only specific file types
grep -r -i "pattern" --include="*.txt" .
grep -r -i "pattern" --include="*.js" --include="*.ts" .
# Exclude directories
grep -r -i "pattern" --exclude-dir=node_modules --exclude-dir=.git .
# Show only filenames (no matches)
grep -r -l -i "pattern" .
# Search with word boundaries
grep -r -w -i "pattern" .
# Count matches per file
grep -r -c -i "pattern" . | grep -v ":0$"
# Complex example: search in JavaScript files, exclude node_modules
grep -r -n -i "function.*user" --include="*.js" --exclude-dir=node_modules .Mac (Additional Options)
bash
# Using grep with find for better control
find . -type f -name "*.txt" -exec grep -i "pattern" {} +
# Search with mdfind (Spotlight)
mdfind "kMDItemTextContent == '*pattern*'c"
# Using ripgrep (faster alternative, install via: brew install ripgrep)
rg -i "pattern"
rg -i "pattern" -g "*.js" # Only .js filesPowerShell
powershell
# Search in current directory
Get-ChildItem -Filter *.txt | Select-String -Pattern "pattern"
# Search recursively
Get-ChildItem -Recurse -Filter *.txt | Select-String -Pattern "pattern"
# Search all files recursively (no filter)
Get-ChildItem -Recurse -File | Select-String -Pattern "pattern"
# Search specific file types
Get-ChildItem -Recurse -Include *.js,*.ts | Select-String -Pattern "pattern"
# Exclude directories
Get-ChildItem -Recurse -File | Where-Object { $_.FullName -notmatch "node_modules|\.git" } | Select-String -Pattern "pattern"
# Show only unique filenames
Get-ChildItem -Recurse -File | Select-String -Pattern "pattern" | Select-Object -Unique Path
# Show filename and line number
Get-ChildItem -Recurse -Include *.txt | Select-String -Pattern "pattern" | Select-Object Path, LineNumber, Line
# Count matches per file
Get-ChildItem -Recurse -Include *.txt | ForEach-Object {
$matches = (Select-String -Path $_.FullName -Pattern "pattern" -AllMatches).Matches.Count
if ($matches -gt 0) {
[PSCustomObject]@{
File = $_.Name
Matches = $matches
}
}
}
# Complex example: search "function" in JavaScript files, exclude node_modules
Get-ChildItem -Recurse -Include *.js |
Where-Object { $_.FullName -notmatch "node_modules" } |
Select-String -Pattern "function.*user"Regular Expressions
Common Patterns
bash
# Email addresses
grep -E -i "[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}" file.txt
# IP addresses
grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" file.txt
# URLs
grep -E -i "https?://[^\s]+" file.txt
# Phone numbers (US format)
grep -E "\(?[0-9]{3}\)?[-. ]?[0-9]{3}[-. ]?[0-9]{4}" file.txt
# Dates (YYYY-MM-DD)
grep -E "[0-9]{4}-[0-9]{2}-[0-9]{2}" file.txtLinux/Mac Regex Options
bash
# Basic regex (default)
grep "pattern" file.txt
# Extended regex
grep -E "pattern1|pattern2" file.txt
# Perl-compatible regex
grep -P "(?<=foo)bar" file.txt # Lookbehind
# Match whole words
grep -w "word" file.txt
# Match at start of line
grep "^pattern" file.txt
# Match at end of line
grep "pattern$" file.txtPowerShell Regex
powershell
# Basic regex
Select-String -Path "file.txt" -Pattern "pattern"
# Multiple patterns (OR)
Select-String -Path "file.txt" -Pattern "pattern1|pattern2"
# Word boundaries
Select-String -Path "file.txt" -Pattern "\bword\b"
# Start of line
Select-String -Path "file.txt" -Pattern "^pattern"
# End of line
Select-String -Path "file.txt" -Pattern "pattern$"
# Extract specific groups
Select-String -Path "file.txt" -Pattern "(\d{4})-(\d{2})-(\d{2})" |
ForEach-Object { $_.Matches.Groups[1..3].Value }Practical Examples
Find TODO Comments in Code
Linux/Mac:
bash
grep -r -n -i "TODO\|FIXME\|HACK" --include="*.js" --include="*.ts" --exclude-dir=node_modules .PowerShell:
powershell
Get-ChildItem -Recurse -Include *.js,*.ts |
Where-Object { $_.FullName -notmatch "node_modules" } |
Select-String -Pattern "TODO|FIXME|HACK"Find API Keys or Secrets
Linux/Mac:
bash
grep -r -n -i "api[_-]?key\|secret\|password" --include="*.js" --include="*.env" --exclude-dir=node_modules .PowerShell:
powershell
Get-ChildItem -Recurse -Include *.js,*.env |
Where-Object { $_.FullName -notmatch "node_modules" } |
Select-String -Pattern "api[_-]?key|secret|password"Find Import Statements
Linux/Mac:
bash
grep -r -n "^import.*from" --include="*.js" --include="*.ts" --exclude-dir=node_modules .PowerShell:
powershell
Get-ChildItem -Recurse -Include *.js,*.ts |
Where-Object { $_.FullName -notmatch "node_modules" } |
Select-String -Pattern "^import.*from"Find Function Definitions
Linux/Mac:
bash
grep -r -n "function\s\+\w\+" --include="*.js" --exclude-dir=node_modules .PowerShell:
powershell
Get-ChildItem -Recurse -Include *.js |
Where-Object { $_.FullName -notmatch "node_modules" } |
Select-String -Pattern "function\s+\w+"Search in Log Files
Linux/Mac:
bash
# Find errors in logs
grep -i "error\|exception\|fatal" /var/log/app.log
# Find errors with context
grep -C 5 -i "error" /var/log/app.log
# Find errors in last hour
find /var/log -name "*.log" -mmin -60 -exec grep -i "error" {} +PowerShell:
powershell
# Find errors in logs
Select-String -Path "C:\logs\app.log" -Pattern "error|exception|fatal"
# Find errors with context
Select-String -Path "C:\logs\app.log" -Pattern "error" -Context 2,3
# Find errors in recent files
Get-ChildItem -Path "C:\logs" -Filter *.log |
Where-Object { $_.LastWriteTime -gt (Get-Date).AddHours(-1) } |
Select-String -Pattern "error"Performance Tips
Linux/Mac
bash
# Use ripgrep (much faster than grep)
brew install ripgrep # Mac
sudo apt install ripgrep # Ubuntu/Debian
rg -i "pattern" # Automatically ignores .git, node_modules, etc.
rg -i "pattern" -g "*.js" # Only .js files
# Use ag (The Silver Searcher)
brew install the_silver_searcher # Mac
sudo apt install silversearcher-ag # Ubuntu/Debian
ag -i "pattern"PowerShell
powershell
# Use -Include with specific extensions instead of searching all files
Get-ChildItem -Recurse -Include *.txt,*.log | Select-String -Pattern "pattern"
# Use -Filter when possible (faster than -Include for single patterns)
Get-ChildItem -Recurse -Filter *.txt | Select-String -Pattern "pattern"
# Limit depth for faster searches
Get-ChildItem -Recurse -Depth 2 -Include *.txt | Select-String -Pattern "pattern"Common Options Comparison
| Feature | Linux/Mac grep | PowerShell Select-String |
|---|---|---|
| Case-insensitive | -i | Default (use -CaseSensitive to disable) |
| Recursive search | -r or -R | Get-ChildItem -Recurse |
| Show line numbers | -n | Included by default |
| Count matches | -c | (Select-String ...).Count |
| Invert match | -v | -NotMatch |
| Show filenames only | -l | Select-Object -Unique Path |
| Context lines | -C num | -Context num,num |
| Multiple patterns | -e pattern1 -e pattern2 | -Pattern "pattern1|pattern2" |
| Exclude directories | --exclude-dir=dir | Where-Object { $_.FullName -notmatch "dir" } |
| File type filter | --include="*.ext" | -Include *.ext |
Aliases and Shortcuts
Linux/Mac
bash
# Add to ~/.bashrc or ~/.zshrc
# Quick recursive grep
alias gr='grep -r -n -i'
# Grep in code files
alias grc='grep -r -n -i --include="*.js" --include="*.ts" --include="*.py" --exclude-dir=node_modules --exclude-dir=.git'
# Find TODO comments
alias todo='grep -r -n "TODO\|FIXME\|HACK" --exclude-dir=node_modules --exclude-dir=.git .'PowerShell
powershell
# Add to $PROFILE
# Quick search function
function Find-Text {
param($Pattern, $Path = ".")
Get-ChildItem -Path $Path -Recurse -File | Select-String -Pattern $Pattern
}
Set-Alias ft Find-Text
# Search in code files
function Find-InCode {
param($Pattern)
Get-ChildItem -Recurse -Include *.js,*.ts,*.py |
Where-Object { $_.FullName -notmatch "node_modules|\.git" } |
Select-String -Pattern $Pattern
}
Set-Alias fic Find-InCodeSee Also
- Cross-Platform Terminal Commands - Command comparisons
- Linux File Operations - File search with find
- Regular Expressions Guide - Test regex patterns online
External Resources
- GNU Grep Manual
- PowerShell Select-String Documentation
- Ripgrep GitHub - Fast grep alternative
- Regex101 - Interactive regex tester