grep — Search file contents for a pattern across all 5 shells
Equivalents in every shell
grep -r "pattern" .grep -r "pattern" .grep -r "pattern" .Select-String -Pattern "pattern" -Path *.txtAliased as `sls`. Outputs match objects, not plain lines.
Worked examples
Recursive case-insensitive search
grep -ri "todo" .Get-ChildItem -Recurse | Select-String -Pattern "todo"findstr /S /I "todo" *Show line numbers
grep -n "error" app.logSelect-String -Pattern "error" -Path app.logfindstr /N "error" app.logInvert match (lines NOT matching)
grep -v "DEBUG" app.logSelect-String -Pattern "DEBUG" -NotMatch -Path app.logfindstr /V "DEBUG" app.logGotchas
- `Select-String` emits objects with `.Line`, `.LineNumber`, `.Path` — pipe to `ForEach { $_.Line }` for plain output.
- cmd `findstr` regex syntax is limited; no `\d`, no lookarounds. Use PowerShell or grep for real regex.
- PowerShell 7+ also exposes `grep` via WSL or `Microsoft.PowerShell.TextUtility` — but `Select-String` is canonical.
WSL & PowerShell Core notes
Related glossary
- Streams & file descriptors
Every Unix process is born with three open files. Knowing which one you are writing to (or reading from) is the difference between a script that works and a script that silently swallows errors.
- Exit codes
An exit code is a one-byte unsigned integer (0–255) the parent reads via `wait()`. The shell exposes it as `$?` (bash/zsh/fish) or `$LASTEXITCODE` (PowerShell, for external programs). Conventions matter.
Common tasks using grep
- Extract a substring by regex
Pull a substring out of a string or a stream of input using a regex — for parsing log lines, extracting an ID from a URL, scraping a version number, or tokenizing a config.
- Extract email addresses from text
Pull every email address out of a log file or block of text.
- Find and replace text in files
Substitute one string for another inside a file (or every file in a tree), in place.
- Find files by name
Locate files matching a glob pattern (e.g. `*.log`) anywhere under the current tree.
- Find which commit introduced a bug
Use `git bisect` to binary-search the history between a known-good and known-bad commit, narrowing thousands of commits to the single guilty one in log₂(N) steps.
- Grep recursively with context lines
Search a directory tree for a pattern and print N lines of surrounding context for each match — for code archaeology, log spelunking, or config-file forensics.
- Pipe command output to grep
Filter the stdout of one command through a pattern matcher and print only matching lines.
- Replace a string across multiple files
Apply the same find-and-replace operation to a batch of files (filtered by glob, by content, or by recursion) — for renaming an API, fixing a typo across a codebase, or updating a config value.
- Show git commit history as a graph
Render the commit DAG as an ASCII graph so branch topology — merges, forks, fast-forwards, and orphan tips — is visible at a glance, instead of the default linear `git log` that hides every parallel branch.