ripgrep (rg) is a line-oriented search tool that recursively searches directories for regex patterns while respecting ignore files. Written in Rust by Andrew Gallant, it combines the usability of grep -r with the speed of a purpose-built search engine. This guide covers architecture, configuration, deployment, performance tuning, security considerations, and developer internals for administrators, packagers, and contributors.
Version covered: ripgrep 15.1.0 | License: MIT OR Unlicense (dual) | MSRV: Rust 1.85.0 | Edition: 2024
For everyday usage, flag examples, and workflow recipes, see the User Guide.
1. Architecture Overview
1.1 Workspace Structure
ripgrep is a Rust workspace containing one binary crate and eight library crates. Each library crate is independently versioned and publishable to crates.io.
ripgrep (binary) crates/core/ v15.1.0
├── grep (facade) crates/grep/ v0.4.1
│ ├── grep-cli crates/cli/ v0.1.12
│ ├── grep-matcher crates/matcher/ v0.1.8
│ ├── grep-regex crates/regex/ v0.1.14
│ ├── grep-pcre2 crates/pcre2/ v0.1.9
│ ├── grep-searcher crates/searcher/ v0.1.16
│ └── grep-printer crates/printer/ v0.3.1
├── globset crates/globset/ v0.4.18
└── ignore crates/ignore/ v0.4.25
| Crate | Role | Key Types |
|---|---|---|
ripgrep (binary) |
CLI entry point, flag parsing, search orchestration | HiArgs, LowArgs, SearchWorker, Printer, PatternMatcher |
grep |
Facade that re-exports all grep-* crates |
-- |
grep-cli |
CLI utilities: decompression, escaping, pattern I/O, TTY detection | DecompressionReader, CommandReader, StandardStream |
grep-matcher |
Abstract Matcher trait and supporting types |
Match, LineTerminator, ByteSet, Matcher trait |
grep-regex |
Rust regex engine adapter implementing Matcher |
RegexMatcher, RegexMatcherBuilder |
grep-pcre2 |
PCRE2 engine adapter implementing Matcher (optional) |
RegexMatcher, RegexMatcherBuilder |
grep-searcher |
Core search engine: reads files/streams, invokes matcher, reports via Sink |
Searcher, Sink, SinkMatch, SinkContext, LineBuffer |
grep-printer |
Output formatting: standard, summary, JSON, hyperlinks, color | Standard, Summary, JSON, PathPrinter, Stats, ColorSpecs |
globset |
High-performance glob matching against multiple patterns simultaneously | Glob, GlobSet, GlobMatcher, GlobBuilder |
ignore |
.gitignore/.ignore/.rgignore parsing plus recursive directory walking |
Walk, WalkParallel, WalkBuilder, Gitignore, Types, Override |
1.2 Execution Flow
main()
└─ run(flags::parse())
├─ flags::parse()
│ ├─ Read RIPGREP_CONFIG_PATH → config args
│ ├─ Merge config args + CLI args
│ ├─ Parse into LowArgs (raw flag values)
│ └─ Convert LowArgs → HiArgs (validated, resolved)
│
└─ match Mode:
├─ Search(single-threaded)
│ ├─ Build: haystack_builder → walk_builder → matcher → searcher → printer
│ ├─ Construct SearchWorker
│ └─ Iterate haystacks sequentially
│
├─ Search(multi-threaded)
│ ├─ Same builder pipeline
│ └─ Use WalkParallel (crossbeam-deque work stealing)
│
├─ Files — list matching files only
├─ Types — list supported file types
└─ Generate — emit completions or man page
1.3 Two-Phase Flag Parsing
Flag parsing uses a deliberate two-phase design (no clap or structopt dependency):
-
LowArgs (
crates/core/flags/lowargs.rs): Raw representation of every flag value exactly as parsed from the command line. Useslexoptfor lightweight argument tokenization. All ~85 flags are defined as unit structs implementing theFlagtrait indefs.rs. -
HiArgs (
crates/core/flags/hiargs.rs): Validated, resolved representation. Cross-flag validation happens here (e.g.,--sortdisables parallelism,--countswitches printer mode). This is the struct that the search pipeline actually consumes.
The Flag trait per flag defines: name_long, name_short, name_negated, doc_short, doc_long, doc_category, doc_variable, and update(). The FLAGS array in defs.rs orders flags for documentation generation.
Note
Shell completions and man pages are generated at runtime via
rg --generate complete-{bash,zsh,fish,powershell}andrg --generate man, not at build time. This ensures they always match the compiled binary exactly.
1.4 Search Pipeline
The search pipeline is a layered composition:
Pattern(s)
→ PatternMatcher (grep-regex or grep-pcre2)
→ Searcher (grep-searcher, manages line buffering + binary detection)
→ Sink (grep-printer: Standard | Summary | JSON)
→ Output (stdout, optionally colored via termcolor)
SearchWorker (crates/core/search.rs) owns one instance of each layer and processes haystacks (files or stdin) one at a time. In multi-threaded mode, each thread gets its own SearchWorker clone.
1.5 Parallel Directory Traversal
The ignore crate's WalkParallel provides parallel directory traversal using crossbeam-deque work-stealing queues. Each worker thread:
- Pops a directory entry from its local deque
- If its deque is empty, steals from another thread's deque
- Applies ignore rules (gitignore, rgignore, overrides) during traversal
- Feeds matching paths to
SearchWorker
Important
When
--sortis specified, ripgrep automatically falls back to single-threaded mode. Sorted output is incompatible with parallel traversal because results must be emitted in deterministic order.
1.6 Ignore File Precedence
Ignore rules are evaluated in a strict precedence order (lowest to highest priority):
| Priority | Source | Notes |
|---|---|---|
| 1 (lowest) | Global gitignore (core.excludesFile from git config) |
System-wide |
| 2 | .gitignore (per-directory, plus parent directories) |
Standard git behavior |
| 3 | .ignore |
ripgrep-specific, same syntax as gitignore |
| 4 | .rgignore |
ripgrep-specific, same syntax as gitignore |
| 5 | --ignore-file PATH |
CLI flag; earlier = lower precedence when specified multiple times |
| 6 (highest) | --glob / --iglob |
Always overrides all ignore files |
1.7 Dependency Map
Runtime dependencies:
| Crate | Version | Role |
|---|---|---|
anyhow |
1.0.75 | Error handling in the binary crate |
bstr |
1.7.0 | Byte string utilities (non-UTF-8 safe) |
lexopt |
0.3.0 | Lightweight CLI argument parsing |
log |
0.4.5 | Logging facade |
serde_json |
1.0.23 | JSON output serialization |
termcolor |
1.1.0 | Cross-platform terminal color output |
textwrap |
0.16.0 | Text wrapping for help output |
tikv-jemallocator |
0.6.0 | jemalloc allocator (musl+64-bit only) |
regex-automata |
0.4.0 | Regex engine backend (DFA/NFA) |
regex-syntax |
0.8.0 | Regex syntax parsing |
aho-corasick |
1.1.1 | Multi-pattern literal matching |
encoding_rs |
0.8.33 | Text encoding support |
encoding_rs_io |
0.1.7 | Streaming encoding transcoder |
memchr |
2.6.3 | Fast single/multi-byte searching |
memmap2 |
0.9.0 | Memory-mapped file I/O |
crossbeam-deque |
0.8.3 | Work-stealing deque for parallel walk |
walkdir |
2.4.0 | Sequential directory traversal |
same-file |
1.0.6 | Cross-platform same-file detection |
pcre2 |
0.2.6 | PCRE2 bindings (optional, behind pcre2 feature) |
winapi-util |
0.1.6 | Windows API utilities (Windows only) |
libc |
0.2.148 | C library bindings (Unix only) |
Dev dependencies: serde 1.0.77, serde_derive 1.0.77.
2. System Requirements
2.1 Supported Platforms
ripgrep targets all major platforms via cross-compilation. Pre-built binaries are published for:
| Platform | Target Triple | Allocator | Notes |
|---|---|---|---|
| Linux x86_64 (glibc) | x86_64-unknown-linux-gnu |
system | Most common |
| Linux x86_64 (musl) | x86_64-unknown-linux-musl |
jemalloc | Static binary, portable |
| Linux aarch64 (gnu) | aarch64-unknown-linux-gnu |
system | ARM64 servers |
| macOS x86_64 | x86_64-apple-darwin |
system | Intel Macs |
| macOS aarch64 | aarch64-apple-darwin |
system | Apple Silicon |
| Windows x86_64 (MSVC) | x86_64-pc-windows-msvc |
system | Recommended for Windows |
| Windows x86_64 (GNU) | x86_64-pc-windows-gnu |
system | MinGW toolchain |
2.2 Build Requirements
| Requirement | Version | Notes |
|---|---|---|
| Rust toolchain | 1.85+ (MSRV) | 2024 edition |
| C compiler | Any | Required for libc bindings; PCRE2 requires C compiler for JIT |
| PCRE2 development headers | 10.21+ | Only if building with --features pcre2 |
| pkg-config | Any | Only for PCRE2 feature on Unix |
2.3 Optional Runtime Dependencies
ripgrep itself is a static binary with zero runtime library dependencies (when using musl). However, some features require external tools at runtime:
| Feature | External Tool | Purpose |
|---|---|---|
--search-zip / -z |
gzip, bzip2, xz, lz4, zstd, brotli, uncompress |
Decompressing archives on the fly |
--pre <cmd> |
User-specified preprocessor | Arbitrary file preprocessing before search |
--hyperlink-format |
Terminal emulator with OSC 8 support | Clickable file links |
Tip
For
--search-zip, ripgrep shells out to external decompression utilities viagrep-cli'sDecompressionReader. Supported formats: gz, bz2, xz, lzma, lz4, zst (zstandard), br (brotli), Z (compress). The decompressor binary must be inPATH.
3. Configuration Reference
3.1 Configuration File
ripgrep reads a configuration file at startup if the RIPGREP_CONFIG_PATH environment variable is set.
# Set in shell profile
export RIPGREP_CONFIG_PATH="$HOME/.ripgreprc"
Config file format:
- One flag per line (long or short form)
- Lines starting with
#are comments - Blank lines are ignored
- Flags that take values use
=or a separate line for the value - No shell expansion or quoting
Example ~/.ripgreprc:
# Search hidden files by default
--hidden
# Use smart case
--smart-case
# Set max columns
--max-columns=150
--max-columns-preview
# Custom type definitions
--type-add=web:*.{html,css,js,ts}
Warning
Config file flags are prepended to CLI args, so CLI flags always override config file flags via last-wins semantics. Negated flags (e.g.,
--no-hidden) can explicitly reverse a config file setting.
3.2 Environment Variables
| Variable | Purpose | Default |
|---|---|---|
RIPGREP_CONFIG_PATH |
Path to configuration file | Not set (no config file) |
NO_COLOR |
Disables all color output when set to any value | Not set |
TERM |
If dumb or unset, disables colors |
Inherited from terminal |
HOME |
Used to locate global gitignore ($HOME/.config/git/ignore) |
System default |
XDG_CONFIG_HOME |
Alternate config directory for global gitignore ($XDG_CONFIG_HOME/git/ignore) |
$HOME/.config |
3.3 Exit Codes
| Code | Meaning |
|---|---|
0 |
At least one match was found |
1 |
No matches found |
2 |
An error occurred (also set when non-fatal errors are encountered, via err_message! macro) |
On Unix, a broken pipe causes graceful exit with code 0 (standard Unix convention).
3.4 Complete Flag Reference
All flags are defined in crates/core/flags/defs.rs. Flags follow last-wins semantics: if a flag is specified multiple times, the last occurrence takes effect. Most boolean flags have a --no- negated form.
3.4.1 Search Behavior
| Long | Short | Type | Default | Description |
|---|---|---|---|---|
--regexp |
-e |
PATTERN |
-- | Specify a pattern. Multiple -e flags are OR'd together. |
--file |
-f |
PATH |
-- | Read patterns from a file, one per line. |
--fixed-strings |
-F |
bool | false |
Treat patterns as literal strings, not regexes. |
--no-fixed-strings |
-- | bool | -- | Negate --fixed-strings. |
--ignore-case |
-i |
bool | false |
Case-insensitive search. |
--no-ignore-case |
-- | bool | -- | Negate --ignore-case. |
--case-sensitive |
-s |
bool | false |
Force case-sensitive search (overrides --smart-case). |
--smart-case |
-S |
bool | false |
Case-insensitive if pattern is all lowercase; case-sensitive otherwise. |
--no-smart-case |
-- | bool | -- | Negate --smart-case. |
--word-regexp |
-w |
bool | false |
Only match whole words. Wraps pattern in \b...\b. |
--no-word-regexp |
-- | bool | -- | Negate --word-regexp. |
--line-regexp |
-x |
bool | false |
Only match whole lines. Wraps pattern in ^...$. |
--no-line-regexp |
-- | bool | -- | Negate --line-regexp. |
--multiline |
-U |
bool | false |
Enable multiline matching. . matches \n. |
--no-multiline |
-- | bool | -- | Negate --multiline. |
--multiline-dotall |
-- | bool | false |
Make . match \n in multiline mode (enabled by default when -U is used). |
--no-multiline-dotall |
-- | bool | -- | Negate --multiline-dotall. |
--crlf |
-- | bool | false |
Treat CRLF (\r\n) as a line terminator. |
--no-crlf |
-- | bool | -- | Negate --crlf. |
--null-data |
-- | bool | false |
Use NUL byte as line terminator instead of \n. |
--no-null-data |
-- | bool | -- | Negate --null-data. |
--invert-match |
-v |
bool | false |
Invert matching: show non-matching lines. |
--no-invert-match |
-- | bool | -- | Negate --invert-match. |
--count |
-c |
bool | false |
Show count of matching lines per file. |
--count-matches |
-- | bool | false |
Show count of individual matches per file (not lines). |
--max-count |
-m |
NUM |
0 (unlimited) |
Stop searching a file after NUM matching lines. |
--only-matching |
-o |
bool | false |
Print only matched parts of a line, each on its own line. |
--no-only-matching |
-- | bool | -- | Negate --only-matching. |
--replace |
-r |
REPLACEMENT |
-- | Replace matches with the given string. Supports capture groups ($1, $name). |
--passthru |
-- | bool | false |
Print both matching and non-matching lines (like cat with highlights). |
--no-passthru |
-- | bool | -- | Negate --passthru. |
--engine |
-- | ENGINE |
default |
Regex engine: default, pcre2, auto. |
--no-engine |
-- | bool | -- | Reset to default engine. |
--pcre2 |
-P |
bool | false |
Use PCRE2 regex engine. Shorthand for --engine=pcre2. |
--no-pcre2 |
-- | bool | -- | Negate --pcre2. |
--auto-hybrid-regex |
-- | bool | false |
Deprecated alias for --engine=auto. |
--no-auto-hybrid-regex |
-- | bool | -- | Negate --auto-hybrid-regex. |
--stop-on-nonmatch |
-- | bool | false |
Stop searching a file after the first non-matching line following a match. Useful for pre-sorted data. |
--no-stop-on-nonmatch |
-- | bool | -- | Negate --stop-on-nonmatch. |
3.4.2 File & Directory Selection
| Long | Short | Type | Default | Description |
|---|---|---|---|---|
--glob |
-g |
GLOB |
-- | Include or exclude files/directories matching the glob. Prefix with ! to exclude. Multiple allowed. |
--iglob |
-- | GLOB |
-- | Case-insensitive --glob. |
--type |
-t |
TYPE |
-- | Only search files matching the named type (e.g., py, js). Multiple allowed. |
--type-not |
-T |
TYPE |
-- | Exclude files matching the named type. Multiple allowed. |
--type-add |
-- | SPEC |
-- | Add a custom file type. Format: NAME:GLOB (e.g., web:*.{html,css,js}). |
--type-clear |
-- | TYPE |
-- | Clear all glob definitions for the named type. |
--type-list |
-- | bool | false |
List all available file types and their globs. |
--hidden |
-. |
bool | false |
Search hidden files and directories (those starting with .). |
--no-hidden |
-- | bool | -- | Negate --hidden (default behavior). |
--binary |
-- | bool | false |
Search binary files. By default, binary files are skipped after a NUL byte is detected. |
--no-binary |
-- | bool | -- | Negate --binary. |
--text |
-a |
bool | false |
Treat binary files as text (search the entire file regardless of NUL bytes). |
--no-text |
-- | bool | -- | Negate --text. |
--follow |
-L |
bool | false |
Follow symbolic links during directory traversal. |
--no-follow |
-- | bool | -- | Negate --follow. |
--one-file-system |
-- | bool | false |
Do not cross filesystem boundaries during traversal. |
--no-one-file-system |
-- | bool | -- | Negate --one-file-system. |
--max-depth |
-d |
NUM |
unlimited | Descend at most NUM directories. --max-depth=0 only searches the start path itself. |
--max-filesize |
-- | SIZE |
unlimited | Skip files larger than SIZE. Accepts suffixes: K, M, G. |
--ignore-file |
-- | PATH |
-- | Additional ignore file (gitignore syntax). Multiple allowed; later = higher precedence. |
--ignore-file-case-insensitive |
-- | bool | false |
Process ignore file globs case-insensitively. |
--no-ignore-file-case-insensitive |
-- | bool | -- | Negate --ignore-file-case-insensitive. |
--no-ignore |
-- | bool | false |
Disable all ignore file processing (gitignore, rgignore, etc.). |
--ignore |
-- | bool | -- | Re-enable ignore file processing. |
--no-ignore-dot |
-- | bool | false |
Disable .ignore and .rgignore processing. |
--ignore-dot |
-- | bool | -- | Re-enable .ignore / .rgignore processing. |
--no-ignore-global |
-- | bool | false |
Disable global gitignore processing. |
--ignore-global |
-- | bool | -- | Re-enable global gitignore processing. |
--no-ignore-parent |
-- | bool | false |
Disable reading .gitignore files from parent directories. |
--ignore-parent |
-- | bool | -- | Re-enable parent .gitignore processing. |
--no-ignore-vcs |
-- | bool | false |
Disable .gitignore processing (but keep .ignore/.rgignore). |
--ignore-vcs |
-- | bool | -- | Re-enable .gitignore processing. |
--no-ignore-exclude |
-- | bool | false |
Disable .git/info/exclude processing. |
--ignore-exclude |
-- | bool | -- | Re-enable .git/info/exclude processing. |
--no-require-git |
-- | bool | false |
Apply .gitignore rules even outside git repositories. |
--require-git |
-- | bool | -- | Only apply .gitignore inside git repos (default). |
--search-zip |
-z |
bool | false |
Search inside compressed files. Requires external decompressor in PATH. |
--no-search-zip |
-- | bool | -- | Negate --search-zip. |
--pre |
-- | COMMAND |
-- | Run each file through COMMAND before searching. The file path is passed as the first argument; ripgrep searches stdout. |
--no-pre |
-- | bool | -- | Disable preprocessor. |
--pre-glob |
-- | GLOB |
-- | Only apply --pre to files matching this glob. Multiple allowed. |
--sort |
-- | CRITERIA |
none | Sort results. Values: path, modified, accessed, created, none. Disables parallelism. |
--sortr |
-- | CRITERIA |
none | Reverse sort. Same values as --sort. Disables parallelism. |
3.4.3 Output Formatting
| Long | Short | Type | Default | Description |
|---|---|---|---|---|
--color |
-- | WHEN |
auto |
When to use colors: never, auto, always, ansi. |
--colors |
-- | SPEC |
-- | Configure specific color settings. Format: {type}:{attribute}:{value}. |
--hyperlink-format |
-- | FORMAT |
-- | Format string for hyperlinks (OSC 8). Placeholders: {path}, {line}, {column}, {host}. |
--no-hyperlink-format |
-- | bool | -- | Disable hyperlinks. |
--heading |
-- | bool | auto | Group matches by file with filename as heading. Default when output is a terminal. |
--no-heading |
-- | bool | -- | Don't group matches by file. Default when output is piped. |
--line-number |
-n |
bool | auto | Show line numbers. Default when output is a terminal. |
--no-line-number |
-N |
bool | -- | Suppress line numbers. |
--column |
-- | bool | false |
Show column number of first match on each line. |
--no-column |
-- | bool | -- | Negate --column. |
--byte-offset |
-b |
bool | false |
Show zero-based byte offset of each matching line. |
--no-byte-offset |
-- | bool | -- | Negate --byte-offset. |
--with-filename |
-H |
bool | auto | Show filename with matches. Default when searching multiple files. |
--no-filename |
-I |
bool | -- | Suppress filename in output. |
--context |
-C |
NUM |
0 |
Show NUM lines of context around each match. |
--after-context |
-A |
NUM |
0 |
Show NUM lines after each match. |
--before-context |
-B |
NUM |
0 |
Show NUM lines before each match. |
--context-separator |
-- | STRING |
-- |
Separator between context groups. |
--no-context-separator |
-- | bool | -- | Disable context separator. |
--field-context-separator |
-- | STRING |
- |
Separator between fields for context lines. |
--field-match-separator |
-- | STRING |
: |
Separator between fields for matching lines. |
--path-separator |
-- | STRING |
OS default | Path separator character. |
--null |
0 |
bool | false |
Use NUL byte after file paths (for use with xargs -0). |
--max-columns |
-M |
NUM |
0 (unlimited) |
Don't print lines longer than NUM bytes. |
--max-columns-preview |
-- | bool | false |
Show a preview of long lines instead of omitting them entirely. |
--no-max-columns-preview |
-- | bool | -- | Negate --max-columns-preview. |
--trim |
-- | bool | false |
Trim leading ASCII whitespace from each line. |
--no-trim |
-- | bool | -- | Negate --trim. |
--vimgrep |
-- | bool | false |
Show results in vim-compatible format (each match on its own line with column). |
--json |
-- | bool | false |
Output results as JSON lines (one JSON object per event). |
--no-json |
-- | bool | -- | Negate --json. |
--stats |
-- | bool | false |
Print aggregate statistics at the end of the search. |
--no-stats |
-- | bool | -- | Negate --stats. |
--include-zero |
-- | bool | false |
With --count, show files with zero matches. |
--no-include-zero |
-- | bool | -- | Negate --include-zero. |
3.4.4 File Listing Modes
| Long | Short | Type | Default | Description |
|---|---|---|---|---|
--files |
-- | bool | false |
List files that would be searched, without searching. |
--files-with-matches |
-l |
bool | false |
Print only names of files containing matches. |
--files-without-match |
-- | bool | false |
Print only names of files containing no matches. |
--no-files-without-match |
-- | bool | -- | Negate --files-without-match. |
3.4.5 Encoding & Input
| Long | Short | Type | Default | Description |
|---|---|---|---|---|
--encoding |
-E |
ENCODING |
auto |
Specify text encoding (e.g., utf-8, euc-jp, latin1). Uses encoding_rs names. |
--no-encoding |
-- | bool | -- | Reset to auto-detection. |
--no-mmap |
-- | bool | false |
Disable memory-mapped I/O. |
--mmap |
-- | bool | -- | Enable memory-mapped I/O. |
--line-buffered |
-- | bool | false |
Force line buffering (flush after each line). |
--no-line-buffered |
-- | bool | -- | Negate --line-buffered. |
--block-buffered |
-- | bool | false |
Force block buffering. |
--no-block-buffered |
-- | bool | -- | Negate --block-buffered. |
3.4.6 Concurrency
| Long | Short | Type | Default | Description |
|---|---|---|---|---|
--threads |
-j |
NUM |
0 (auto) |
Number of threads for parallel search. 0 means auto-detect based on available cores. |
3.4.7 Logging & Debugging
| Long | Short | Type | Default | Description |
|---|---|---|---|---|
--debug |
-- | bool | false |
Show debug messages (written to stderr). |
--no-debug |
-- | bool | -- | Negate --debug. |
--trace |
-- | bool | false |
Show trace-level debug messages (very verbose). |
--no-trace |
-- | bool | -- | Negate --trace. |
--no-messages |
-- | bool | false |
Suppress error messages (e.g., permission denied). |
--messages |
-- | bool | -- | Re-enable error messages. |
--no-unicode |
-- | bool | false |
Disable Unicode support in regex patterns. |
--unicode |
-- | bool | -- | Re-enable Unicode support. |
3.4.8 Meta / Output Generation
| Long | Short | Type | Default | Description |
|---|---|---|---|---|
--help |
-h |
bool | -- | Print short help. Use --help for long-form verbose help. |
--version |
-V |
bool | -- | Print version information. |
--generate |
-- | KIND |
-- | Generate auxiliary files: complete-bash, complete-zsh, complete-fish, complete-powershell, man. |
--hostname-bin |
-- | COMMAND |
-- | Command to run to get hostname (for {host} in --hyperlink-format). |
4. Deployment & Scaling
4.1 Building from Source
# Standard release build
git clone https://github.com/BurntSushi/ripgrep
cd ripgrep
cargo build --release
# Binary at: target/release/rg
# Optimized release with LTO (smaller, faster, slower to compile)
cargo build --profile release-lto
# Binary at: target/release-lto/rg
# With PCRE2 support
cargo build --release --features pcre2
# Debian package (requires cargo-deb)
cargo install cargo-deb
cargo deb --profile deb
4.2 Build Profiles
| Profile | LTO | Debug Info | Strip | Panic | Codegen Units | Use Case |
|---|---|---|---|---|---|---|
release |
no | 1 (line tables) |
no | unwind | default | Development releases |
release-lto |
fat | 0 |
yes | abort | 1 | Production binaries |
deb |
inherits release-lto |
0 |
yes | abort | 1 | .deb packages |
4.3 Feature Flags
| Feature | Default | Effect |
|---|---|---|
pcre2 |
off | Enables the grep-pcre2 crate, linking against libpcre2-8. Requires PCRE2 development headers and a C compiler. |
4.4 Allocator Selection
The allocator is selected at compile time via build.rs:
| Condition | Allocator |
|---|---|
target_env = "musl" AND 64-bit |
tikv-jemallocator (jemalloc) |
| All other targets | System allocator |
Note
jemalloc is used on musl+64-bit targets because musl's built-in allocator has known performance regressions with allocation-heavy workloads. On glibc targets, the system allocator is generally competitive with jemalloc.
4.5 Cross-Compilation
ripgrep supports cross-compilation via standard Rust toolchains:
# Example: build for aarch64 Linux from x86_64
rustup target add aarch64-unknown-linux-gnu
cargo build --release --target aarch64-unknown-linux-gnu
# Using cross (recommended for cross-compilation with C dependencies like PCRE2)
cargo install cross
cross build --release --target aarch64-unknown-linux-musl
4.6 Package Distribution
Shell completions (generate and install):
# Bash
rg --generate complete-bash > /usr/share/bash-completion/completions/rg
# Zsh
rg --generate complete-zsh > /usr/local/share/zsh/site-functions/_rg
# Fish
rg --generate complete-fish > /usr/share/fish/vendor_completions.d/rg.fish
# PowerShell
rg --generate complete-powershell | Out-File -Encoding utf8 -FilePath "$env:USERPROFILE\Documents\PowerShell\Completions\rg.ps1"
Man page:
rg --generate man > /usr/local/share/man/man1/rg.1
4.7 Static Binary Builds
For fully static, zero-dependency binaries:
# Build static musl binary (Linux)
cargo build --release --target x86_64-unknown-linux-musl
# Result: standalone ~6MB binary, no shared library dependencies
This is the recommended approach for containerized deployments:
# Multi-stage build for minimal image
FROM rust:1.85-slim AS builder
RUN apt-get update && apt-get install -y pkg-config musl-tools
WORKDIR /build
COPY . .
RUN rustup target add x86_64-unknown-linux-musl
RUN cargo build --profile release-lto --target x86_64-unknown-linux-musl
FROM scratch
COPY --from=builder /build/target/x86_64-unknown-linux-musl/release-lto/rg /rg
ENTRYPOINT ["/rg"]
5. Operations
5.1 Debugging and Diagnostics
Debug output shows which files are searched, which are skipped, and why:
# Show debug messages
rg --debug PATTERN
# Show trace-level detail (very verbose — shows every ignore rule evaluation)
rg --trace PATTERN
Debug output goes to stderr, so it can be captured separately:
rg --debug PATTERN 2>debug.log
Common debug output patterns:
| Message Pattern | Meaning |
|---|---|
ignoring <path>: matched ignore pattern |
File excluded by gitignore/rgignore |
binary file matches |
NUL byte detected, file skipped |
<path>: Permission denied |
OS-level permission error |
skipping <path>: max filesize exceeded |
File exceeds --max-filesize |
Statistics provide aggregate search metrics:
rg --stats PATTERN
# Output includes: files searched, files matched, lines matched,
# matches found, bytes searched, time elapsed
5.2 Search Modes
| Mode | Activated By | Behavior |
|---|---|---|
| Search (default) | rg PATTERN [PATH...] |
Search for matches and print results |
| Count | --count / -c |
Print match count per file |
| Count matches | --count-matches |
Print individual match count (not lines) per file |
| Files with matches | --files-with-matches / -l |
Print only filenames with matches |
| Files without match | --files-without-match |
Print only filenames without matches |
| List files | --files |
List all files that would be searched |
| List types | --type-list |
List all known file types |
| Generate | --generate KIND |
Emit shell completions or man page |
5.3 JSON Output Format
The --json flag outputs structured JSON lines, one per event. Event types:
| Event | Description | Key Fields |
|---|---|---|
begin |
Start of a file search | path |
end |
End of a file search | path, stats |
match |
A matching line | path, lines, line_number, submatches |
context |
A context line | path, lines, line_number |
summary |
Final statistics | elapsed_total, stats |
# Pipe JSON output to jq for processing
rg --json PATTERN | jq 'select(.type == "match") | .data.submatches'
Tip
JSON output is stable and machine-parseable. It is the recommended format for programmatic consumption of ripgrep results. Each line is a self-contained JSON object, making it compatible with streaming JSON processors like
jq.
5.4 Binary File Handling
ripgrep uses a NUL-byte heuristic to detect binary files:
| Flag | Behavior |
|---|---|
| (default) | If a NUL byte is found in the first few KB, stop searching the file and print a notification |
--binary |
Search binary files but still report binary detection |
--text / -a |
Treat all files as text (search entire contents regardless of NUL bytes) |
--no-binary |
Skip binary files entirely (no notification printed) |
5.5 Memory-Mapped I/O
ripgrep can use memory-mapped I/O for reading files. The decision is made heuristically by default, but can be overridden:
# Force memory-mapped I/O
rg --mmap PATTERN
# Disable memory-mapped I/O
rg --no-mmap PATTERN
Caution
Memory-mapped I/O can cause
SIGBUSon Unix systems if a file is truncated while being read. ripgrep installs aSIGBUShandler to deal with this gracefully, but--no-mmapavoids the issue entirely. Additionally, memory-mapped I/O is generally slower when searching many small files due to page fault overhead.
5.6 Handling Large-Scale Searches
For searching very large codebases or directory trees:
# Limit thread count to reduce memory pressure
rg -j4 PATTERN /large/tree
# Skip large files (e.g., vendored bundles, generated code)
rg --max-filesize 1M PATTERN
# Limit traversal depth
rg --max-depth 5 PATTERN
# Stay on one filesystem (avoid NFS, tmpfs, etc.)
rg --one-file-system PATTERN
# Suppress permission errors to reduce noise
rg --no-messages PATTERN /
6. Performance
6.1 Performance Architecture
ripgrep's speed comes from several architectural decisions working together:
-
Regex engine selection: Uses
regex-automatawhich compiles patterns to DFA or NFA state machines. For literal patterns, it extracts literals and usesmemchroraho-corasickfor fast scanning before engaging the full regex engine. -
Parallel traversal: The
ignorecrate'sWalkParallelusescrossbeam-dequework-stealing for efficient parallel directory traversal. Each thread has its own search stack. -
Ignore-during-walk:
.gitignorerules are evaluated during directory traversal, not after. Entire directory trees can be pruned without reading their contents. -
Line-oriented searching:
grep-searcherreads in large chunks (default 64KB buffer) and scans for line terminators and matches simultaneously, minimizing passes over the data. -
Allocation minimization: The
bstrcrate and careful buffer reuse minimize allocations in the hot path.
6.2 Thread Tuning
# Use exactly 4 threads
rg -j4 PATTERN
# Use 1 thread (single-threaded mode, deterministic output order)
rg -j1 PATTERN
# Use all available cores (default)
rg -j0 PATTERN
The default (-j0) detects available CPU cores via std::thread::available_parallelism(). For I/O-bound searches (network filesystems, spinning disks), reducing thread count may improve throughput by reducing seek contention.
6.3 Performance-Impacting Flags
| Flag | Performance Impact | Why |
|---|---|---|
--sort / --sortr |
Disables parallelism entirely | Must collect and sort all results |
--pcre2 / -P |
Slower for simple patterns | PCRE2 engine is generally slower than Rust regex for non-backtracking patterns |
--multiline / -U |
Slower | Must process entire file as one unit instead of line-by-line |
--search-zip / -z |
Much slower | Must decompress each file via external process |
--pre |
Much slower | Must fork and exec external command per file |
--no-ignore |
Mixed | Skips ignore file parsing but searches more files total |
--mmap |
Mixed | Faster for large files on SSDs; slower for many small files |
--text / -a |
Neutral | Only disables binary detection heuristic |
--encoding |
Slightly slower | Must transcode file contents through encoding_rs |
--no-unicode |
Faster | Disables Unicode character class tables in regex engine |
--fixed-strings / -F |
Faster | Enables pure literal matching, bypasses regex compilation |
6.4 Benchmarking
ripgrep includes a benchmark suite at benchsuite/benchsuite (Python script):
cd benchsuite
python benchsuite --help
The benchmark suite compares ripgrep against:
grep(GNU)git grepag(The Silver Searcher)ugrep
Tip
For accurate benchmarks, drop filesystem caches before each run:
sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'on Linux. Run each benchmark multiple times to account for variance. The benchsuite uses a corpus of real-world data (Linux kernel source, subtitles, etc.) for representative measurements.
7. Security
7.1 Security Model
ripgrep is a local tool that reads files and writes to stdout. Its security surface:
| Surface | Risk | Mitigation |
|---|---|---|
| Regex patterns | ReDoS (catastrophic backtracking) | Rust regex engine guarantees linear time (no backtracking). PCRE2 engine (-P) does allow backtracking. |
| File traversal | Symlink following | Symlinks are NOT followed by default. --follow / -L enables traversal. |
| File traversal | Symlink loops | The ignore crate detects and breaks symlink cycles. |
| Preprocessor | Arbitrary code execution | --pre runs arbitrary commands; only use trusted preprocessors. |
| Decompression | Zip bombs / decompression bombs | --search-zip shells out to decompressor utilities; they handle their own limits. |
| Input patterns | Untrusted pattern injection | Patterns from files (-f) or args (-e) are executed as regexes. Use --fixed-strings for untrusted input. |
| Config file | Privilege escalation | RIPGREP_CONFIG_PATH could point to an attacker-controlled file. Only set in trusted environments. |
| Binary detection | Information disclosure | NUL-byte heuristic may miss some binary files. --no-binary is more conservative. |
7.2 Regex Engine Safety
The default Rust regex engine provides guaranteed linear-time matching:
- No catastrophic backtracking
- No ReDoS vulnerability
- Bounded memory usage proportional to pattern size
- No backreferences (by design)
Warning
The PCRE2 engine (
--pcre2/-P) does NOT guarantee linear time. Patterns with backreferences or complex lookaround can exhibit exponential time complexity. Do not use--pcre2with untrusted patterns in security-sensitive contexts.
7.3 Safe Usage with Untrusted Input
# Safe: treat user input as literal string
rg --fixed-strings -- "$USER_INPUT" /path
# Safe: read patterns from file, treated as literals
rg --fixed-strings -f patterns.txt /path
# Unsafe: user input interpreted as regex
rg "$USER_INPUT" /path # DO NOT do this with untrusted input
# Note: use -- to prevent patterns starting with - from being parsed as flags
rg --fixed-strings -- "$USER_INPUT" /path
7.4 File System Safety
- ripgrep does not follow symlinks unless
--followis explicitly passed - The
--one-file-systemflag prevents crossing mount boundaries (useful in containers or to avoid NFS mounts) --max-depthlimits traversal depth, preventing runaway searches in deep directory trees--max-filesizelimits per-file read size, preventing memory exhaustion on large files
Caution
When running ripgrep in environments where the file tree is partially controlled by untrusted users (e.g., shared hosting, CI with untrusted repos), be aware that maliciously crafted
.gitignoreor.rgignorefiles can influence which files are skipped. Use--no-ignoreto disable all ignore file processing in such environments.
8. Developer Internals
8.1 Source Layout
crates/
core/ Binary crate (rg)
main.rs Entry point: main() → run()
search.rs SearchWorker: owns matcher + searcher + printer
haystack.rs Haystack construction and filtering
logger.rs Log initialization (env_logger-style)
flags/
mod.rs Flag trait, Category enum, FlagValue
defs.rs ~85 flag definitions (unit structs implementing Flag)
parse.rs CLI argument parser → LowArgs
lowargs.rs LowArgs struct (raw flag values)
hiargs.rs HiArgs struct (validated, resolved)
config.rs Config file parser (RIPGREP_CONFIG_PATH)
complete/ Shell completion generators
bash.rs Bash completion script
zsh.rs Zsh completion script
fish.rs Fish completion script
powershell.rs PowerShell completion script
doc/
help.rs Help text generation (short + long)
man.rs Man page (roff) generation
grep/ Facade crate (re-exports grep-*)
cli/ CLI utilities
decompress.rs DecompressionReader (external decompressor process)
escape.rs Byte string escaping
pattern.rs Pattern I/O (read from file, stdin)
wtr.rs StandardStream (TTY-aware writer)
matcher/ Matcher trait
interpolate.rs Capture group interpolation ($1, $name)
regex/ Rust regex adapter
ast.rs AST analysis for optimization
config.rs RegexMatcherBuilder config
error.rs Error types
literal.rs Literal extraction for acceleration
non_matching.rs Non-matching byte detection
strip.rs Pattern stripping utilities
word.rs Word boundary handling
pcre2/ PCRE2 adapter (optional feature)
error.rs PCRE2 error types
matcher.rs PCRE2 Matcher implementation
searcher/ Core search engine
searcher/
core.rs Searcher implementation
glue.rs Searcher-to-Matcher glue logic
line_buffer.rs Line-oriented buffered reading (64KB default)
sink.rs Sink trait and implementations
printer/ Output printers
standard.rs Standard human-readable output (grep-like)
summary.rs Summary output (counts, file lists)
json.rs JSON lines output format
hyperlink.rs OSC 8 hyperlink generation
color.rs Color specification parsing
stats.rs Search statistics accumulation
util.rs Shared printer utilities
globset/ Glob matching library
glob.rs Glob parsing and compilation to regex
fnmatch.rs fnmatch-style matching
pathutil.rs Path normalization utilities
serde_impl.rs Serde Serialize/Deserialize for Glob
ignore/ Ignore + directory walking
walk.rs Walk (sequential) and WalkParallel (crossbeam-deque)
dir.rs Per-directory ignore rule management
gitignore.rs .gitignore file parser
overrides.rs CLI --glob override rules
types.rs Built-in file type definitions and matching
pathutil.rs Path utilities (is_hidden, strip_prefix, etc.)
tests/
tests.rs Integration test entry point (imports all test modules)
binary.rs Binary file handling tests
feature.rs Feature-specific tests (types, globs, etc.)
json.rs JSON output format tests
misc.rs Miscellaneous tests
multiline.rs Multiline matching tests
regression.rs Regression tests (linked to GitHub issues)
hay.rs Test haystack helpers (create temp dirs with test data)
util.rs Test utilities (run rg binary, assert output)
macros.rs Test assertion macros
data/ Test data (sherlock.txt in various compressed formats)
benchsuite/
benchsuite Python benchmark runner script
fuzz/
fuzz_targets/
fuzz_glob.rs Fuzz target for globset glob parsing
ci/
sha256-releases Generate SHA256 checksums for release artifacts
test-complete Validate generated shell completions
ubuntu-install-packages Install build dependencies on Ubuntu
utils.sh Shared CI utility functions
8.2 Adding a New Flag
Each flag is a unit struct implementing the Flag trait in crates/core/flags/defs.rs. To add a new flag:
- Define the struct and implement
Flag:
/// --my-new-flag
#[derive(Debug)]
struct FlagMyNewFlag;
impl Flag for FlagMyNewFlag {
fn is_switch(&self) -> bool { true }
fn name_long(&self) -> &'static str { "my-new-flag" }
fn name_short(&self) -> Option<u8> { None }
fn name_negated(&self) -> Option<&'static str> { Some("no-my-new-flag") }
fn doc_category(&self) -> Category { Category::Search }
fn doc_short(&self) -> &'static str { "Short description." }
fn doc_long(&self) -> &'static str { "Long description..." }
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
args.my_new_flag = v.unwrap_switch();
Ok(())
}
}
- Add the field to
LowArgsinlowargs.rs. - Add the flag to the
FLAGSarray indefs.rs, maintaining alphabetical order. - Wire it into
HiArgsinhiargs.rsfor validation and resolution. - Use it in the search pipeline (e.g.,
search.rs,haystack.rs). - Add tests: inline
#[test]functions in the flag definition, plus integration tests intests/.
8.3 The Matcher Trait
The grep-matcher crate defines the abstract Matcher trait that makes ripgrep engine-agnostic:
pub trait Matcher {
type Captures: Captures;
type Error: std::fmt::Display;
fn find_at(
&self, haystack: &[u8], at: usize,
) -> Result<Option<Match>, Self::Error>;
fn new_captures(
&self,
) -> Result<Self::Captures, Self::Error>;
fn captures_at(
&self, haystack: &[u8], at: usize, caps: &mut Self::Captures,
) -> Result<bool, Self::Error>;
// Additional methods with default implementations:
// find(), find_iter(), captures(), captures_iter(),
// replace(), replace_with_captures(), etc.
}
Both grep-regex::RegexMatcher and grep-pcre2::RegexMatcher implement this trait. Custom regex engines can be integrated by providing a Matcher implementation.
The Match type is a simple (start, end) byte offset pair. LineTerminator controls what constitutes a line boundary. ByteSet is a bitset over byte values used for fast character class membership tests.
8.4 The Sink Trait
The grep-searcher crate's Sink trait is the output callback interface:
pub trait Sink {
type Error;
fn matched(
&mut self, searcher: &Searcher, mat: &SinkMatch<'_>,
) -> Result<bool, Self::Error>;
// Optional methods with defaults:
fn context(
&mut self, _: &Searcher, _: &SinkContext<'_>,
) -> Result<bool, Self::Error> { Ok(true) }
fn begin(
&mut self, _: &Searcher,
) -> Result<bool, Self::Error> { Ok(true) }
fn finish(
&mut self, _: &Searcher, _: &SinkFinish,
) -> Result<(), Self::Error> { Ok(()) }
}
The grep-printer crate provides three Sink implementations:
| Implementation | Output Format | Use Case |
|---|---|---|
Standard |
Human-readable, grep-like, with optional color | Terminal output |
Summary |
File-level summaries (counts, paths only) | --count, --files-with-matches |
JSON |
Machine-readable JSON lines | --json, programmatic consumption |
The return value of matched() and context() controls whether searching continues (true) or stops early (false), enabling features like --max-count.
8.5 The Ignore Crate — Reusable Library
The ignore crate is one of ripgrep's most widely reused components. It is used by many other tools (fd, tokei, etc.) for fast, gitignore-aware directory traversal.
WalkBuilder: Configures directory traversal with ignore rules, file type filters, and parallelism.
use ignore::WalkBuilder;
// Sequential walk
for entry in WalkBuilder::new("./src").build() {
let entry = entry.unwrap();
println!("{}", entry.path().display());
}
// Parallel walk
WalkBuilder::new("./src")
.hidden(false) // search hidden files
.git_ignore(true) // respect .gitignore
.follow_links(false) // don't follow symlinks
.threads(4) // parallel walk threads
.build_parallel()
.run(|| {
Box::new(|entry| {
// Process entry in worker thread
ignore::WalkState::Continue
})
});
Gitignore: Parses and evaluates .gitignore rules. Can be used standalone without directory traversal.
Types: File type matching based on glob patterns. Includes ~150 built-in file type definitions.
8.6 The Globset Crate — Reusable Library
globset is a standalone crate for high-performance glob matching. Its key feature is GlobSet, which compiles multiple globs into a single regex for simultaneous matching in one pass:
use globset::{Glob, GlobSetBuilder};
let mut builder = GlobSetBuilder::new();
builder.add(Glob::new("*.rs")?);
builder.add(Glob::new("*.toml")?);
let set = builder.build()?;
// Returns indices of all matching globs
let matches: Vec<usize> = set.matches("src/main.rs");
assert!(set.is_match("src/main.rs"));
Glob syntax supported:
*— matches any sequence of non-path-separator characters**— matches any sequence of characters, including path separators?— matches any single non-path-separator character[abc]— character class[!abc]/[^abc]— negated character class{a,b,c}— alternation
8.7 Error Handling
- The binary crate uses
anyhowfor error propagation with context - Library crates define their own error types (no
anyhowdependency in libraries) - The
err_message!macro in the binary crate prints non-fatal errors to stderr and sets the exit code to2 - Broken pipe errors (
std::io::ErrorKind::BrokenPipe) are caught and cause a graceful exit with code0 - The
HiArgsconversion phase (LowArgs -> HiArgs) performs cross-flag validation and reports conflicts as errors
8.8 Testing
Unit tests: Each flag in defs.rs has inline #[test] functions testing parsing behavior for positive, negative, and edge cases.
Integration tests (tests/): End-to-end tests that invoke rg as a subprocess and assert on stdout/stderr content:
# Run all tests
cargo test
# Run only integration tests
cargo test --test tests
# Run a specific test module
cargo test --test tests -- regression
# Run tests with PCRE2
cargo test --features pcre2
Test infrastructure (tests/util.rs): Provides a Dir builder that creates temporary directories with test files, runs rg against them, and asserts on output. The rgtest! macro (in macros.rs) simplifies test definitions.
Fuzz testing: The fuzz/ directory contains a fuzzing target for globset glob parsing:
cargo install cargo-fuzz
cargo fuzz run fuzz_glob
8.9 CI Pipeline
The ci/ directory contains CI support scripts:
| Script | Purpose |
|---|---|
ci/sha256-releases |
Generate SHA256 checksums for release artifacts |
ci/test-complete |
Validate that generated shell completion scripts parse correctly |
ci/ubuntu-install-packages |
Install build dependencies on Ubuntu CI runners (including PCRE2 headers) |
ci/utils.sh |
Shared CI utility functions (target detection, artifact naming) |
8.10 build.rs
The build.rs script reads two environment variables set by Cargo:
| Variable | Purpose |
|---|---|
CARGO_CFG_TARGET_OS |
Detects target OS for platform-specific conditional compilation |
CARGO_CFG_TARGET_ENV |
Detects target environment (e.g., musl vs gnu) for allocator selection |
The build script emits cargo:rustc-cfg directives that control conditional compilation in main.rs (e.g., jemalloc usage on musl).
9. Integration Points
9.1 As a Library
ripgrep's library crates are published to crates.io independently. The grep facade crate provides a single dependency that re-exports all grep-* crates:
[dependencies]
grep = "0.4"
For selective usage (smaller dependency tree):
[dependencies]
grep-searcher = "0.1"
grep-regex = "0.1"
grep-printer = "0.3"
The ignore and globset crates are particularly popular as standalone libraries:
[dependencies]
ignore = "0.4" # gitignore-aware directory walking
globset = "0.4" # high-performance glob matching
9.2 Editor Integration
ripgrep is widely integrated into code editors:
| Editor | Integration | Configuration |
|---|---|---|
| VS Code | Built-in (workspace search engine) | search.useRipgrep setting |
| Neovim | Native grepprg support |
:set grepprg=rg\ --vimgrep |
| Emacs | rg.el, counsel-rg, deadgrep |
Package-specific config |
| Sublime Text | Plugin ecosystem | Plugin-specific config |
| IntelliJ IDEA | Plugin available | Plugin-specific config |
The --vimgrep flag produces output compatible with vim's errorformat:
file.rs:10:5:matched text here
9.3 Shell Integration
Pipe-friendly defaults: When stdout is not a TTY, ripgrep automatically:
- Disables colors
- Disables headings
- Enables line numbers
xargs integration:
# NUL-separated output for safe filename handling
rg --files --null | xargs -0 wc -l
rg -l --null PATTERN | xargs -0 sed -i 's/old/new/g'
fzf integration:
# Interactive ripgrep with fzf preview
rg --line-number --color=always PATTERN | \
fzf --ansi --preview 'bat --color=always {1} --highlight-line {2}'
9.4 JSON Output for Tooling
The --json output format enables programmatic integration:
# Count matches per file using jq
rg --json PATTERN | \
jq -r 'select(.type == "end") | "\(.data.path.text): \(.data.stats.matches)"'
# Extract matched text only
rg --json PATTERN | \
jq -r 'select(.type == "match") | .data.submatches[].match.text'
# Get file paths with matches
rg --json PATTERN | \
jq -r 'select(.type == "begin") | .data.path.text'
9.5 Preprocessor Integration
The --pre flag enables arbitrary file preprocessing:
# Search inside PDF files using pdftotext
rg --pre pdftotext --pre-glob '*.pdf' PATTERN
# Search inside Word documents
rg --pre 'pandoc --to=plain' --pre-glob '*.docx' PATTERN
# Search inside SQLite databases
rg --pre 'sqlite3 -csv' --pre-glob '*.db' PATTERN
Important
The
--precommand receives the file path as its first argument and must write the searchable text to stdout. It runs once per file, so this is significantly slower than direct file searching. Always use--pre-globto limit preprocessing to specific file types.
9.6 Compressed File Search
ripgrep delegates decompression to external utilities via grep-cli's DecompressionReader:
| Format | Extension | Decompressor Command |
|---|---|---|
| gzip | .gz |
gzip -d -c |
| bzip2 | .bz2 |
bzip2 -d -c |
| xz | .xz |
xz -d -c |
| lzma | .lzma |
xz --format=lzma -d -c |
| lz4 | .lz4 |
lz4 -d -c |
| zstandard | .zst |
zstd -d -c |
| brotli | .br |
brotli -d -c |
| compress | .Z |
uncompress -c |
# Search all compressed files in a directory
rg -z PATTERN /var/log/
Note
Compressed file format detection uses file extensions, not content sniffing (see GitHub issue #3342). Files with incorrect or missing extensions will not be decompressed. Use
--prewith a content-aware tool for extension-independent detection.
9.7 Known Issues and Workarounds
Sourced from the project's GitHub issue tracker:
| Issue | Description | Workaround |
|---|---|---|
| #3262 | $F treated as capture group in replacement despite --fixed-strings |
Escape the $ in the replacement string, or avoid --replace with --fixed-strings when replacement contains $ |
| #3277 | Config file reported as not working | Verify RIPGREP_CONFIG_PATH is set and exported; use --debug to confirm config file loading |
| #3286 | Panic with walk builder min_depth/max_depth edge cases | Avoid setting min_depth greater than max_depth |
| #3309 | Regex error messages could be more descriptive | Use --debug for additional context on pattern compilation failures |
| #3342 | --search-zip uses file extension, not content detection |
Rename files with correct extensions, or use --pre for content-based detection |
| #3364 | Unexpected output with --multiline --pcre2 --json combined |
Avoid combining all three flags; use the default regex engine for multiline JSON output |