ripgrep (rg) is a line-oriented search tool that recursively searches directories for regex patterns while respecting gitignore rules. It is fast, cross-platform, and designed as a modern replacement for grep. ripgrep runs on Windows, macOS, and Linux with first-class support on all three.
Version covered: 15.1.0 | Binary name: rg | License: Unlicense OR MIT
1. Quick Start
Your First Search
Search for a word in the current directory:
rg "TODO"
Expected output:
src/main.rs:42: // TODO: refactor this function
src/lib.rs:107: // TODO: add error handling
tests/test_core.rs:15: // TODO: parameterize
ripgrep searches recursively, skips binary files, respects .gitignore, and highlights matches — all by default.
Five Commands to Get Started
# Search for a pattern in a specific directory
rg "pattern" ./src/
# Case-insensitive search
rg -i "error"
# Search only Python files
rg -t py "import requests"
# Show 3 lines of context around matches
rg -C 3 "panic"
# Count matches per file
rg -c "TODO"
Tip
Run
rg --helpfor a compact flag summary, orrg -hfor a brief overview. The full manual page can be generated withrg --generate man.
2. Installation
Package Managers
| Platform | Command |
|---|---|
| macOS (Homebrew) | brew install ripgrep |
| macOS (MacPorts) | sudo port install ripgrep |
| Ubuntu/Debian | sudo apt install ripgrep |
| Fedora | sudo dnf install ripgrep |
| Arch Linux | sudo pacman -S ripgrep |
| Windows (Chocolatey) | choco install ripgrep |
| Windows (Scoop) | scoop install ripgrep |
| Windows (winget) | winget install BurntSushi.ripgrep.MSVC |
| Cargo (any OS) | cargo install ripgrep |
| Nix | nix-env -i ripgrep |
From GitHub Releases
Download prebuilt binaries from github.com/BurntSushi/ripgrep/releases. Archives contain the rg binary and shell completions.
# Example: Linux x86_64
curl -LO https://github.com/BurntSushi/ripgrep/releases/download/14.1.1/ripgrep-14.1.1-x86_64-unknown-linux-musl.tar.gz
tar xzf ripgrep-14.1.1-x86_64-unknown-linux-musl.tar.gz
sudo cp ripgrep-14.1.1-x86_64-unknown-linux-musl/rg /usr/local/bin/
Verify Installation
rg --version
Expected output:
ripgrep 15.1.0
Shell Completions
ripgrep can generate completion scripts for your shell:
# Bash
rg --generate complete-bash > ~/.local/share/bash-completion/completions/rg
# Zsh
rg --generate complete-zsh > ~/.zfunc/_rg
# Fish
rg --generate complete-fish > ~/.config/fish/completions/rg.fish
# PowerShell
rg --generate complete-powershell >> $PROFILE
Man Page
rg --generate man > rg.1
sudo cp rg.1 /usr/local/share/man/man1/
3. Configuration
Config File
ripgrep reads a configuration file from the path specified by the RIPGREP_CONFIG_PATH environment variable. There is no default config file location — you must set this variable explicitly.
# Set up a config file (add to your shell profile)
export RIPGREP_CONFIG_PATH="$HOME/.config/ripgrep/config"
Config file format — one flag per line:
# Search settings
--smart-case
--hidden
--glob=!.git
# Output settings
--color=always
--heading
--line-number
# Max columns for readability
--max-columns=200
--max-columns-preview
Important
Arguments in the config file are prepended to any arguments you pass on the command line. CLI arguments always take precedence because they come last and override earlier conflicting flags.
Disabling the Config File
# Temporarily ignore your config
rg --no-config "pattern"
Ignore Files
ripgrep honors several ignore file formats, applied in this precedence order (highest precedence last):
| File | Scope | Purpose |
|---|---|---|
.gitignore |
Per-directory | Standard git ignores |
.ignore |
Per-directory | ripgrep + other tools (fd, etc.) |
.rgignore |
Per-directory | ripgrep-specific ignores |
| Global gitignore | User-wide | Git's core.excludesFile |
--ignore-file PATH |
Per-invocation | Extra ignore files via CLI |
All ignore files use gitignore syntax. Later sources override earlier ones, and patterns within the same file are applied in order (last match wins).
Example .rgignore:
# Skip build artifacts
target/
dist/
node_modules/
# Skip generated files
*.generated.*
*.min.js
4. Core Usage
Basic Pattern Matching
# Simple string search
rg "hello world"
# Regex search (default)
rg "fn\s+\w+\("
# Fixed-string search (no regex interpretation)
rg -F "user.name()"
# Search a specific file
rg "pattern" path/to/file.rs
# Search a specific directory
rg "pattern" src/
Case Sensitivity
# Case sensitive (default)
rg -s "Error"
# Case insensitive
rg -i "error"
# Smart case: insensitive if pattern is all lowercase,
# sensitive if it contains any uppercase
rg -S "error" # matches Error, ERROR, error
rg -S "Error" # matches only Error
Tip
Add
--smart-caseto your config file — it is the most practical default for everyday searching. You can override with-swhen you need exact case matching.
Multiple Patterns
# OR: match any of these patterns
rg -e "TODO" -e "FIXME" -e "HACK"
# Read patterns from a file (one per line)
rg -f patterns.txt
# Read patterns from stdin
echo "pattern" | rg -f -
# Combine file and CLI patterns
rg -f patterns.txt -e "additional_pattern"
Regex Syntax
ripgrep uses Rust's regex engine by default. Common patterns:
| Pattern | Meaning |
|---|---|
. |
Any character (except newline) |
\d |
Digit [0-9] |
\w |
Word character [a-zA-Z0-9_] |
\s |
Whitespace |
\b |
Word boundary |
^ / $ |
Start / end of line |
(a|b) |
Alternation |
[abc] |
Character class |
[^abc] |
Negated character class |
x{3} |
Exactly 3 repetitions |
x{2,5} |
2 to 5 repetitions |
x+? |
Non-greedy one-or-more |
(?:...) |
Non-capturing group |
(?P<name>...) |
Named capture group |
(?i) |
Inline case-insensitive flag |
# IP addresses
rg "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
# Email-like patterns
rg "\b[\w.+-]+@[\w-]+\.[\w.]+\b"
# Function definitions in Python
rg "def \w+\(.*\):"
# URLs
rg "https?://\S+"
Multiline Matching
# Enable multiline mode
rg -U "struct \w+ \{[^}]*\}"
# Dot matches newlines too
rg -U --multiline-dotall "BEGIN.*?END"
PCRE2 Engine
For advanced regex features (backreferences, lookaheads), use the PCRE2 engine:
# Enable PCRE2
rg -P "(\w+)\s+\1" # backreference: repeated word
rg -P "(?<=fn )\w+" # lookbehind: word after "fn "
rg -P "foo(?=\()" # lookahead: "foo" followed by "("
# Auto engine: tries default first, falls back to PCRE2
rg --engine auto "(\w+)\s+\1"
Note
PCRE2 support is an optional compile-time feature. Run
rg --pcre2-versionto check if your build includes it. If not, you will see an error when using-P.
Word and Line Matching
# Match whole words only (adds \b boundaries)
rg -w "error" # matches "error" but not "errors" or "terror"
# Match entire lines
rg -x "use std::io;" # only lines that are exactly "use std::io;"
Inverted Matching
# Show lines that do NOT match
rg -v "^#" # all non-comment lines
rg -v "^\s*$" # all non-empty lines
5. Common Tasks
5.1 Search Only Certain File Types
ripgrep has 150+ built-in file type definitions:
# Search only Rust files
rg -t rust "unwrap()"
# Search only JavaScript and TypeScript
rg -t js -t ts "addEventListener"
# Exclude test files
rg -T test "fn main"
# List all built-in types
rg --type-list
Expected output from --type-list (excerpt):
c: *.c, *.h
cpp: *.cpp, *.cc, *.cxx, *.hpp, *.hh, *.hxx, *.h, *.inl
js: *.js, *.mjs, *.cjs, *.jsx
py: *.py, *.pyi
rust: *.rs
...
Custom File Types
# Define a custom type for this invocation
rg --type-add "web:*.html" --type-add "web:*.css" --type-add "web:*.js" -t web "TODO"
# Clear an existing type's definitions
rg --type-clear js --type-add "js:*.mjs" -t js "import"
# Add types via config file for persistent use
# In your config: --type-add=config:*.yaml,*.yml,*.toml,*.json
5.2 Filter Files with Globs
# Only search .go files
rg -g "*.go" "func main"
# Exclude test files
rg -g "!*_test.go" "func main"
# Multiple globs
rg -g "*.rs" -g "!tests/*" "pub fn"
# Case-insensitive globs
rg --iglob "*.Readme" "license"
# Only search in a specific directory pattern
rg -g "src/**/*.py" "import"
5.3 Replace Text (Preview)
ripgrep can show replacements without modifying files:
# Simple replacement
rg "foo" -r "bar"
# Using capture groups
rg "(\w+)\.unwrap\(\)" -r '${1}.expect("failed")'
# Named capture groups
rg "(?P<year>\d{4})-(?P<month>\d{2})" -r '${month}/${year}'
# Remove matched text (replace with empty)
rg "// TODO:.*" -r ""
Warning
The
-r/--replaceflag only changes what ripgrep prints to stdout. It does not modify files on disk. To apply changes, pipe throughsed, use your editor, or a dedicated refactoring tool.
5.4 Context Around Matches
# 5 lines after each match
rg -A 5 "fn main"
# 3 lines before each match
rg -B 3 "panic!"
# 2 lines before and after (context)
rg -C 2 "error"
# Custom context separator
rg -C 2 --context-separator "===" "error"
# No context separator
rg -C 2 --no-context-separator "error"
# Show ALL lines, highlighting matches (like grep --color + cat)
rg --passthru "TODO" src/main.rs
5.5 Count Matches
# Count matching lines per file
rg -c "TODO"
Expected output:
src/main.rs:3
src/lib.rs:7
tests/test_core.rs:1
# Count individual matches (not lines)
rg --count-matches "the" README.md
# Include files with zero matches
rg -c --include-zero "TODO"
5.6 List Files Only
# Files with matches
rg -l "TODO"
# Files without matches
rg --files-without-match "TODO"
# Files that WOULD be searched (no pattern needed)
rg --files
# Combine with globs to see what files match a filter
rg --files -g "*.rs"
5.7 Search Hidden Files and Ignored Files
By default, ripgrep skips hidden files (dotfiles), files matched by .gitignore, and binary files.
# Include hidden files (dotfiles)
rg --hidden "API_KEY"
# Ignore .gitignore rules
rg --no-ignore "password"
# Ignore all ignore files (.gitignore, .ignore, .rgignore)
rg --no-ignore "debug"
# Search everything: no-ignore + hidden + binary
rg -uuu "pattern"
The -u flag is cumulative:
| Flag | Effect |
|---|---|
-u |
--no-ignore — skip ignore rules |
-uu |
--no-ignore --hidden — also search hidden files |
-uuu |
--no-ignore --hidden --binary — search everything |
5.8 Search Compressed Files
# Search inside compressed files (gz, bz2, xz, lzma, lz4, zst)
rg -z "ERROR" /var/log/
# Combine with type filters
rg -z -t log "FATAL" /var/log/
Supported compressed formats: .gz, .bz2, .xz, .lzma, .lz4, .zst, .br, .Z
5.9 Search with Specific Encodings
# Auto-detect encoding (default)
rg "pattern"
# Specify encoding explicitly
rg -E utf-16 "pattern" file.txt
rg -E shift_jis "pattern" japanese_text.txt
rg -E euc-jp "pattern" legacy_file.txt
# Disable encoding detection (search raw bytes)
rg --no-encoding "pattern"
5.10 Sorted Output
# Sort results by file path (deterministic output)
rg --sort path "TODO"
# Sort by modification time (newest last)
rg --sort modified "TODO"
# Reverse sort (newest first)
rg --sortr modified "TODO"
# Sort options: path, modified, accessed, created
Note
Sorting disables parallelism, which makes searches slower. Use it only when you need deterministic or ordered output.
5.11 Limit Search Depth and File Size
# Only search 2 levels deep
rg --max-depth 2 "pattern"
# Skip files larger than 1MB
rg --max-filesize 1M "pattern"
# Skip files larger than 500KB
rg --max-filesize 500K "pattern"
5.12 Follow Symlinks
# Follow symbolic links (off by default)
rg -L "pattern"
5.13 JSON Output for Scripting
# Machine-readable JSON Lines output
rg --json "pattern"
Each line is a JSON object with a type field. Five message types:
| Type | When | Key Fields |
|---|---|---|
begin |
Start of a file | path |
match |
Each match | path, lines, line_number, submatches |
context |
Context lines | path, lines, line_number |
end |
End of a file | path, stats |
summary |
End of search | elapsed_total, stats |
Text data uses a text field for valid UTF-8, or a bytes field with base64 encoding for non-UTF-8 content.
# Pipe to jq for processing
rg --json "TODO" | jq 'select(.type == "match") | .data.lines.text'
# Extract just the matched text from each match
rg --json "TODO" | jq -r 'select(.type == "match") | .data.submatches[].match.text'
5.14 Preprocessor for Unsupported Formats
# Use a preprocessor to search PDFs
rg --pre "pdftotext {} -" "pattern" docs/
# Only apply preprocessor to PDF files
rg --pre "pdftotext {} -" --pre-glob "*.pdf" "pattern" docs/
# Search Word documents
rg --pre "catdoc" --pre-glob "*.doc" "pattern" documents/
5.15 Vim-Compatible Output
# One match per line, with column numbers (for :grep in Vim)
rg --vimgrep "pattern"
Expected output:
src/main.rs:42:5: // TODO: refactor this function
src/main.rs:42:18: // TODO: refactor this function
Set in your .vimrc:
set grepprg=rg\ --vimgrep
set grepformat=%f:%l:%c:%m
6. Troubleshooting
Exit Codes
| Code | Meaning |
|---|---|
0 |
At least one match found (or successful special operation like --type-list) |
1 |
No matches found |
2 |
An error occurred |
Error: No matches found (exit code 1)
Cause: The pattern did not match any content in the searched files, or files were filtered out before searching.
Solution:
- Verify your pattern is correct:
rg -F "exact string"to avoid regex issues. - Check if files are being ignored:
rg --debug "pattern" 2>&1 | head -20to see which files are skipped and why. - Try relaxing filters:
rg -uuu "pattern"to search everything. - List files that would be searched:
rg --files | headto confirm your target files are included.
Error: regex parse error
Cause: The search pattern contains invalid regex syntax. Characters like (, ), [, {, ., *, +, ?, |, ^, $, \ have special meaning in regex.
Solution:
# Use fixed-string mode to search for literal text
rg -F "function()" src/
# Or escape special characters
rg "function\(\)" src/
Prevention: When searching for code snippets that contain regex metacharacters, always use -F (fixed strings).
Error: PCRE2 is not available
Cause: Your ripgrep binary was compiled without PCRE2 support, but you used -P or --engine pcre2.
Solution:
# Check if PCRE2 is available
rg --pcre2-version
# If not available, install a build with PCRE2:
cargo install ripgrep --features pcre2
# Or on macOS:
brew install ripgrep
Error: binary file matches (hidden by default)
Cause: ripgrep detected binary content in a file and suppressed the output.
Solution:
# Show binary file matches as text
rg -a "pattern"
# Or explicitly enable binary searching
rg --binary "pattern"
# Or make ripgrep search everything
rg -uuu "pattern"
Error: file not searched due to ignore rules
Cause: The file matches a pattern in .gitignore, .ignore, .rgignore, or a global ignore file.
Solution:
# See WHY a file is being ignored
rg --debug "pattern" 2>&1 | grep -i "ignore"
# Bypass all ignore rules
rg --no-ignore "pattern"
# Bypass only .gitignore
rg --no-ignore-vcs "pattern"
# Bypass only global gitignore
rg --no-ignore-global "pattern"
Error: $ treated as capture group in replacement with --fixed-strings
Cause: Even when using -F/--fixed-strings for the search pattern, the replacement string (-r) still interprets $1, $2, ${name} as capture group references.
Solution:
# Escape dollar signs in the replacement
rg -F "search" -r "\$variable"
Problem: Search is too slow
Cause: Several factors can slow ripgrep: sorted output, following symlinks into large trees, searching compressed files, or PCRE2 patterns.
Solution:
- Remove
--sort/--sortrif deterministic output is not required. - Check for symlink loops: avoid
-Lin directories with circular links. - Limit scope: use
-g,-t,--max-depth, or--max-filesize. - Avoid
--pcre2unless you need backreferences or lookaround. - Use
--statsto see timing breakdown.
rg --stats "pattern" src/
Problem: Matches not highlighted in piped output
Cause: ripgrep automatically disables colors when stdout is not a terminal (a pipe or redirect).
Solution:
# Force colors even when piping
rg --color always "pattern" | less -R
# Use --pretty for heading + line numbers + color
rg -p "pattern" | less -R
Problem: Config file not loading
Cause: The RIPGREP_CONFIG_PATH environment variable is not set, or points to a non-existent file.
Solution:
# Verify the variable is set
echo $RIPGREP_CONFIG_PATH
# Verify the file exists
cat "$RIPGREP_CONFIG_PATH"
# Test with debug output
rg --debug "test" 2>&1 | grep -i "config"
Prevention: Add the export to your shell profile (~/.bashrc, ~/.zshrc, $PROFILE for PowerShell).
Problem: Different results on different machines
Cause: Different ignore files, config files, or ripgrep versions across machines.
Solution:
# Compare versions
rg --version
# Run without any config
rg --no-config "pattern"
# Run with no ignore rules and hidden files
rg -uuu "pattern"
# Show debug info to see what's being loaded
rg --debug "pattern" 2>&1 | head -30
Problem: Searching in non-git directories skips files unexpectedly
Cause: By default, ripgrep looks for a .git directory to determine the repository root for ignore processing. Without one, certain ignore behaviors may not work as expected.
Solution:
# Allow searching without a git repository
rg --no-require-git "pattern"
Problem: Windows path separators in output
Cause: ripgrep uses the OS-native path separator by default.
Solution:
# Force forward slashes on Windows
rg --path-separator / "pattern"
Problem: Multiline matches with PCRE2 and JSON output produce unexpected results
Cause: When combining --multiline, --pcre2, and --json, certain edge cases in line boundary detection can produce unexpected output formatting.
Solution:
# Use the default regex engine for multiline JSON output when possible
rg -U --json "pattern"
# If you must use PCRE2, verify output with a small test first
rg -P -U --json "pattern" test_file.txt
Problem: Error messages cluttering output
Cause: Permission errors, broken symlinks, or unreadable files produce warnings on stderr.
Solution:
# Suppress all error messages
rg --no-messages "pattern"
# Suppress only ignore-file parse errors
rg --no-ignore-messages "pattern"
# Redirect stderr to separate from results
rg "pattern" 2>/dev/null
Caution
When using
--debugor--tracefor troubleshooting, be aware that these flags produce verbose output on stderr. Redirect stderr to a file for easier analysis:rg --debug "pattern" 2>debug.log.
7. FAQ
Q: How is ripgrep different from grep?
ripgrep is faster than GNU grep in most scenarios because it uses parallelism, memory-mapped I/O, and the Rust regex engine. It also automatically skips binary files, respects .gitignore, and uses smart defaults (recursive search, colored output on terminals). Unlike grep, ripgrep does not support the BRE (basic regular expression) syntax — it always uses a modern regex syntax similar to Perl and RE2.
Q: Can ripgrep replace files in-place like sed?
No. The --replace flag only changes what is printed to stdout. ripgrep is a search tool, not an editing tool. To modify files, pipe ripgrep output into sed, awk, or use your editor's search-and-replace. For example:
# Preview replacements
rg "old_name" -r "new_name"
# Apply with sed (GNU sed)
rg -l "old_name" | xargs sed -i 's/old_name/new_name/g'
Q: How do I search for a pattern that starts with a dash?
Use -- to signal the end of flags, or use -e:
rg -- "-TODO"
rg -e "-TODO"
Q: Can I search only filenames, not contents?
Use rg --files combined with a pipe to filter:
# Find files with "test" in their name
rg --files | rg "test"
# Using globs
rg --files -g "*test*"
Q: How do I match across multiple lines?
Use the -U (multiline) flag:
# Match a struct definition spanning multiple lines
rg -U "struct \w+ \{[^}]*\}"
# Use --multiline-dotall to make . match newlines
rg -U --multiline-dotall "BEGIN.*?END"
Q: Why does ripgrep skip my .env file?
.env is a hidden file (starts with .). By default ripgrep skips hidden files. Additionally, .env is commonly listed in .gitignore. Use --hidden and/or --no-ignore to include it:
rg --hidden --no-ignore "API_KEY" .env
Q: How do I use ripgrep with xargs or find?
Use -0/--null to NUL-terminate filenames for safe piping:
# Search specific files found by find
find . -name "*.log" -print0 | xargs -0 rg "ERROR"
# Use ripgrep's own file listing with NUL separation
rg --files -0 -g "*.py" | xargs -0 rg "import os"
Q: Can I make ripgrep ignore certain directories permanently?
Yes. Add patterns to any of the supported ignore files:
# Project-specific: create .rgignore in the project root
echo "vendor/" >> .rgignore
echo "node_modules/" >> .rgignore
echo "*.min.js" >> .rgignore
# Or use .ignore (also respected by fd and other tools)
echo "build/" >> .ignore
Q: How do I get ripgrep to show only the matched text, not the whole line?
Use -o (only-matching):
rg -o "\d+\.\d+\.\d+" Cargo.toml
Output:
0.15.1
1.2.3
Q: What is the --stop-on-nonmatch flag for?
It tells ripgrep to stop searching a file after the first non-matching line is encountered (when using context flags). This is useful for structured files like logs where matches are expected to be contiguous at the beginning or end of the file.
Q: Does ripgrep support lookahead and lookbehind?
Not with the default regex engine. Use -P (PCRE2) for these features:
# Lookbehind: find words after "version: "
rg -P "(?<=version: )\S+"
# Lookahead: find "import" followed by "React"
rg -P "import(?=.*React)"
# Negative lookahead: "error" not followed by "handling"
rg -P "error(?!.*handling)"
Q: How do I add hyperlinks to matches in my terminal?
If your terminal supports OSC 8 hyperlinks:
# Enable file:// hyperlinks
rg --hyperlink-format default "pattern"
# Use grep+ format for click-to-line support
rg --hyperlink-format "grep+" "pattern"
Q: Can I limit the number of matches shown?
Yes, use -m/--max-count:
# Show at most 5 matches per file
rg -m 5 "TODO"
# Show at most 1 match per file (first match only)
rg -m 1 "TODO"
Q: How do I customize colors?
Use --colors with the format {type}:{attribute}:{value}:
# Red matches on yellow background
rg --colors "match:fg:red" --colors "match:bg:yellow" "pattern"
# Bold green filenames
rg --colors "path:fg:green" --colors "path:style:bold" "pattern"
# Types: path, line, column, match, highlight
# Attributes: fg, bg, style
# Colors: red, green, blue, yellow, magenta, cyan, white, black
# Styles: bold, nobold, intense, nointense, underline, nounderline
Add these to your config file for persistent styling.
Q: How do I search stdin instead of files?
When no file path is given and stdin is not a terminal, ripgrep reads from stdin:
# Pipe data to ripgrep
cat server.log | rg "ERROR"
# Combine with other commands
docker logs mycontainer 2>&1 | rg "timeout"
Q: What does the --crlf flag do?
It tells ripgrep to treat \r\n (Windows-style line endings) as line terminators. This affects how $ anchors work in patterns — with --crlf, the $ matches before the \r\n rather than between \r and \n.
rg --crlf "pattern$" windows_file.txt
Q: How do I prevent ripgrep from crossing filesystem boundaries?
Use the --one-file-system flag to stay on the same filesystem when recursing:
rg --one-file-system "pattern" /
This is useful on Linux when you want to avoid searching into mounted filesystems like /proc, /sys, or network mounts.
Important
For architecture details, configuration deep-dives, performance tuning, regex engine internals, and crate-level API documentation, see the Admin Guide.
Quick Reference Card
Most-Used Flags
| Flag | Purpose |
|---|---|
-i |
Case insensitive |
-S |
Smart case |
-F |
Fixed strings (no regex) |
-w |
Whole word match |
-v |
Invert match |
-c |
Count matches per file |
-l |
List matching files only |
-o |
Print only matched text |
-n |
Show line numbers |
-C NUM |
Context lines (before + after) |
-A NUM |
Lines after match |
-B NUM |
Lines before match |
-t TYPE |
Only search file type |
-T TYPE |
Exclude file type |
-g GLOB |
Include/exclude by glob |
-r REPL |
Replace match in output |
-z |
Search compressed files |
-U |
Multiline matching |
-P |
PCRE2 regex engine |
-p |
Pretty output (color + heading + line numbers) |
-u |
Unrestricted (cumulative) |
-m NUM |
Max matches per file |
-M NUM |
Max columns per line |
--hidden |
Include hidden files |
--no-ignore |
Skip ignore rules |
--sort path |
Deterministic sorted output |
--json |
JSON Lines output |
--stats |
Print search statistics |
--debug |
Debug output on stderr |
Cheat Sheet
# Find all TODO/FIXME/HACK comments
rg -e "TODO" -e "FIXME" -e "HACK"
# Find function definitions with context
rg -t rust "fn \w+\(" -A 2
# Find files containing "password" (hidden + ignored files too)
rg -uu -l "password"
# Count files per file type that would be searched
rg --files -t py | wc -l
# Search gzipped logs for errors
rg -z "ERROR" /var/log/app/*.gz
# Preview a rename refactor
rg "OldClassName" -r "NewClassName"
# Get match statistics
rg --stats "pattern" src/ 2>&1 | tail -6
# JSON output piped to jq — extract matching filenames
rg --json "TODO" | jq -r 'select(.type == "begin") | .data.path.text'
# Find lines NOT containing a pattern
rg -v "^(#|$)" config.ini
# Search with byte offset (for binary analysis)
rg -b "magic_bytes"
# Trim leading whitespace from output
rg --trim "pattern"
# NUL-separated output for safe scripting
rg -l -0 "pattern" | xargs -0 wc -l