Lightning-fast recursive search tool that combines the usability of ag with the speed of grep. Respects .gitignore rules by default.
| Platform | Command |
|---|
| macOS (Homebrew) | brew install ripgrep |
| Ubuntu/Debian | sudo apt install ripgrep |
| Arch Linux | sudo pacman -S ripgrep |
| Fedora | sudo dnf install ripgrep |
| Windows (Scoop) | scoop install ripgrep |
| Windows (Choco) | choco install ripgrep |
| Cargo (Rust) | cargo install ripgrep |
| Verify | rg --version |
| Command | Description |
|---|
rg "pattern" | Search recursively in current directory |
rg "pattern" path/ | Search in specific directory |
rg "pattern" file.txt | Search in specific file |
rg -i "pattern" | Case-insensitive search |
rg -S "pattern" | Smart case (insensitive if all lowercase) |
rg -w "word" | Match whole words only |
rg -c "pattern" | Count matches per file |
rg -l "pattern" | List files with matches only |
rg --files-without-match "pattern" | List files without matches |
rg -n "pattern" | Show line numbers (default) |
rg -N "pattern" | Hide line numbers |
rg --column "pattern" | Show column numbers of matches |
rg -F "literal.string" | Fixed string search (no regex) |
| Command | Description |
|---|
rg "foo|bar" | Match foo OR bar |
rg "^import" | Lines starting with “import” |
rg ";\s*$" | Lines ending with semicolon |
rg "\d{3}-\d{4}" | Match phone number pattern |
rg "\bfunction\b" | Word boundary matching |
rg "fn\s+\w+" | Match function definitions |
rg -P "(?<=@)\w+" | PCRE2 lookbehind (extract domain) |
rg -P "\b\w{20,}\b" | Words with 20+ characters |
rg -U "struct \{[\s\S]*?\}" | Multiline matching |
rg -e "pat1" -e "pat2" | Multiple patterns (OR logic) |
rg -f patterns.txt | Read patterns from file |
| Command | Description |
|---|
rg -A 3 "pattern" | Show 3 lines after match |
rg -B 2 "pattern" | Show 2 lines before match |
rg -C 5 "pattern" | Show 5 lines of context (before + after) |
rg -o "pattern" | Print only the matched text |
rg --json "pattern" | Output in JSON format |
rg --vimgrep "pattern" | Output in Vim-compatible format |
rg --color never "pattern" | Disable color output |
rg --color always "pattern" | less -R | Force color for piping |
rg --heading "pattern" | Group results by file (default in terminal) |
rg --no-heading "pattern" | Single-line results without grouping |
rg --trim "pattern" | Trim whitespace from results |
rg -m 5 "pattern" | Limit to 5 matches per file |
rg --max-count 1 "pattern" | First match per file only |
rg --stats "pattern" | Show search statistics at end |
rg --passthru "pattern" | Show all lines, highlighting matches |
| Command | Description |
|---|
rg -t py "pattern" | Search only Python files |
rg -t js -t ts "pattern" | Search JavaScript and TypeScript files |
rg -T html "pattern" | Exclude HTML files |
rg -g "*.md" "pattern" | Glob filter — only markdown files |
rg -g "!*.min.js" "pattern" | Glob exclude — skip minified JS |
rg -g "src/**/*.ts" "pattern" | Glob with directory path |
rg -g "!test/" "pattern" | Exclude test directory |
rg --type-list | Show all known file types |
rg --type-add 'web:*.{html,css,js}' | Define custom file type |
| Command | Description |
|---|
rg --hidden "pattern" | Include hidden files/directories |
rg --no-ignore "pattern" | Don’t respect .gitignore rules |
rg --no-ignore-vcs "pattern" | Skip only VCS ignore files |
rg -u "pattern" | Unrestricted (—no-ignore) |
rg -uu "pattern" | More unrestricted (—no-ignore —hidden) |
rg -uuu "pattern" | Most unrestricted (+ binary files) |
rg --max-depth 2 "pattern" | Limit directory depth |
rg -L "pattern" | Follow symbolic links |
rg --max-filesize 1M "pattern" | Skip files larger than 1MB |
rg --sort path "pattern" | Sort results by file path |
rg --sortr modified "pattern" | Sort by modification time (newest first) |
rg --files | List all files rg would search |
rg --files -t rust | List all Rust files |
| Command | Description |
|---|
rg "old" -r "new" | Preview replacements (stdout only) |
rg "(\w+)@(\w+)" -r '$1 at $2' | Regex capture group replacement |
rg "TODO" -r "DONE" --passthru | Show full file with replacements |
rg -l "oldFunc" | xargs sed -i 's/oldFunc/newFunc/g' | Actually replace in files (with sed) |
| File/Variable | Description |
|---|
~/.ripgreprc | Default config file |
RIPGREP_CONFIG_PATH | Custom config file path |
--no-config | Ignore config file |
--smart-case
--line-number
--heading
--max-columns=200
--max-columns-preview
--glob=!node_modules/
--glob=!.git/
--glob=!dist/
--glob=!vendor/
--colors=match:fg:yellow
--colors=match:style:bold
--colors=path:fg:green
# All TODOs with context
rg "TODO|FIXME|HACK|XXX" -t py -C 2
# Count TODOs per file
rg -c "TODO" --sort path
# Preview changes
rg "oldFunction" -r "newFunction" -t js
# Apply changes (pipe to sed)
rg -l "oldFunction" -t js | xargs sed -i 's/oldFunction/newFunction/g'
# Find files that don't contain a pattern
rg --files-without-match "Copyright" -t py
# Find unused exports
rg "export " -t ts -l | while read f; do
rg -l "$(basename $f .ts)" -g "!$f" || echo "Unused: $f"
done
# Search compressed logs
rg -z "ERROR" /var/log/*.gz
# Extract timestamps from errors
rg -o "\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*ERROR.*" app.log
# Count errors per day
rg -o "^\d{4}-\d{2}-\d{2}" --no-filename error.log | sort | uniq -c
# Interactive file selection with fzf
rg --files | fzf --preview 'rg --color=always "pattern" {}'
# Feed results to vim
rg --vimgrep "pattern" | vim -q /dev/stdin
# JSON pipeline with jq
rg --json "pattern" | jq 'select(.type == "match") | .data.lines.text'
| Tool | Speed | .gitignore | Unicode | Regex |
|---|
| ripgrep | Fastest | ✅ Yes | ✅ Full | ✅ Rust regex + PCRE2 |
| grep -r | Slow | ❌ No | ⚠️ Partial | ✅ POSIX/extended |
| ag (Silver Searcher) | Fast | ✅ Yes | ✅ Full | ✅ PCRE |
| ack | Moderate | ❌ No | ✅ Full | ✅ Perl |
- Use file type filters (
-t, -T) instead of globs when possible — they’re faster and cover all extensions
- Create a
.ripgreprc to set smart-case, heading, and directory exclusions as defaults
- Use
.ignore files in project roots to exclude node_modules, dist, build without affecting git
- Prefer
-F for literal strings containing regex metacharacters to avoid escaping
- Use
--stats to understand search performance on large codebases
- Combine with
fzf or xargs for interactive selection and batch operations
- Use
--files first to verify which files will be searched before running the actual search
- Use multiline mode (
-U) sparingly — it’s slower; prefer multiple searches when possible
| Issue | Solution |
|---|
| Missing results in git repo | Files may be in .gitignore — use rg -u or --no-ignore |
| Binary file skipped | Use rg -uuu or --text to include binary files |
| Regex not matching | Try -P for PCRE2 engine, or -F for literal strings |
No results with \b | Default engine may not support — try rg -P "\bword\b" |
| Colors missing in pipe | Use --color always when piping to less or other tools |
| Config not loading | Check RIPGREP_CONFIG_PATH or use --no-config to debug |
| Symlinks not followed | Add -L or --follow flag |
| Results too noisy | Use -g '!pattern' globs or -t type to narrow scope |
| Search too slow | Use --max-filesize, reduce depth with --max-depth, or filter types |