- cli
- l1
- topic-pack
- ripgrep --- Portal | Level: L1: Foundations | Topics: ripgrep (rg) | Domain: CLI Tools
ripgrep (rg) — Fast Search Primer¶
Why This Matters¶
ripgrep is grep rebuilt for modern codebases. It is faster than grep, ag, and ack in nearly every benchmark. It respects .gitignore by default, supports PCRE2 regex, and handles Unicode correctly. For DevOps engineers searching through logs, configs, and code across large repos, rg eliminates the wait.
Name origin: ripgrep (rg) was created by Andrew Galloway in 2016, written in Rust. The "rip" stands for both speed ("ripping through files") and the Rust implementation. In benchmarks, rg is typically 2-10x faster than grep on large directory searches because it uses memory-mapped I/O, parallelism, and avoids searching inside .git directories.
Fun fact: ripgrep powers the search in VS Code, Sublime Text, and many other editors. When you use Ctrl+Shift+F in VS Code, it is ripgrep doing the work.
Core Concepts¶
Basic Search¶
# Search for a pattern in the current directory (recursive by default)
rg "connection refused"
# Search a specific file
rg "timeout" /etc/nginx/nginx.conf
# Search a specific directory
rg "ERROR" /var/log/
rg is recursive by default — no -r flag needed. It automatically skips binary files and respects .gitignore.
Gotcha: rg exits with code 1 when no matches are found — this trips up shell scripts using
set -e. Userg "pattern" || trueor check$?explicitly if "no matches" is an expected outcome.
Case Sensitivity¶
# Case-insensitive
rg -i "error"
# Smart case (case-insensitive unless pattern has uppercase)
rg -S "Error"
Output Control¶
Line Numbers and Context¶
# Show line numbers (default when outputting to terminal)
rg -n "segfault" /var/log/syslog
# Lines before match
rg -B 3 "panic" app.log
# Lines after match
rg -A 5 "FATAL" app.log
# Lines before and after
rg -C 2 "OOMKilled" events.log
Count and Files Only¶
# Count matches per file
rg -c "TODO" src/
# List files with matches (no content)
rg -l "password"
# List files WITHOUT matches
rg --files-without-match "license" .
Type Filters¶
rg has built-in file-type awareness:
# Search only Python files
rg -t py "import requests"
# Search only YAML files
rg -t yaml "replicas:"
# Exclude a type
rg -T js "config"
# List known types
rg --type-list
Common types: py, go, js, ts, yaml, json, md, sh, tf, docker.
Glob Patterns¶
Fine-grained file filtering:
# Only search .conf files
rg -g '*.conf' "listen"
# Exclude test directories
rg -g '!tests/' -g '!*_test.go' "func "
# Only Helm templates
rg -g 'templates/*.yaml' "{{ .Values"
Regular Expressions¶
rg uses Rust regex by default (fast). Add -P for PCRE2 (lookaheads, backreferences):
# Standard regex
rg "error|warn|fatal" /var/log/syslog
# Word boundary
rg -w "port" # matches "port" but not "export"
# PCRE2 with capture groups
rg -P "timeout=(\d+)" --only-matching
Replace¶
rg can preview replacements (does not modify files):
rg "oldfunction" --replace "newfunction"
# Pipe to sed for actual file modification
rg -l "oldvalue" | xargs sed -i 's/oldvalue/newvalue/g'
Hidden Files and Ignores¶
# Include hidden files (dotfiles)
rg --hidden "secret"
# Include files ignored by .gitignore
rg --no-ignore "TODO"
# Include everything (hidden + ignored + binary)
rg -uuu "pattern"
The -u flag stacks:
| Flag | Effect |
|------|--------|
| -u | Include .gitignore'd files |
| -uu | Also include hidden files |
| -uuu | Also include binary files |
Configuration File¶
Set RIPGREP_CONFIG_PATH to a file with one flag per line (e.g., --smart-case, --glob=!.git/). These apply to every rg invocation.
One-liner:
export RIPGREP_CONFIG_PATH="$HOME/.ripgreprc"then add--smart-caseand--max-columns=200to the file. Smart case (case-insensitive unless your pattern has uppercase) is the single most useful default.
rg vs grep¶
rg is multi-threaded, .gitignore-aware, Unicode-complete, recursive by default, and skips binary files. Typical speedup is 2-10x on large repos.
Remember: When to still use grep: inside containers (rg is not installed), parsing single files where speed does not matter, and when you need POSIX portability across AIX/Solaris/FreeBSD. For everything else, rg wins. Mnemonic: "rg for repos, grep for pipes" — use rg for directory searches, grep for filtering piped output.
Under the hood: rg's speed comes from three design decisions: (1) it uses memory-mapped I/O to avoid read syscall overhead, (2) it parallelizes directory traversal across CPU cores, and (3) it uses Rust's
regexcrate which compiles patterns to automata — avoiding the exponential backtracking that slows grep on pathological patterns.
Practical DevOps Patterns¶
# Find all hardcoded IPs
rg -P '\b\d{1,3}(\.\d{1,3}){3}\b' --type yaml
# Find secrets that should not be in code
rg -i "(password|secret|api.?key)\s*[:=]" --type-not md
# Search compressed logs
zcat /var/log/syslog.1.gz | rg "error"
# rg + fzf: interactive search results
rg --color=always "TODO" | fzf --ansi
Wiki Navigation¶
Related Content¶
- Modern CLI Drills (Drill, L0) — ripgrep (rg)
- Modern CLI Tools (Topic Pack, L0) — ripgrep (rg)
- Ripgrep Flashcards (CLI) (flashcard_deck, L1) — ripgrep (rg)
- Skillcheck: Modern CLI Tools (Assessment, L0) — ripgrep (rg)