Basics of rg
rg is ripgrep, a fast command-line tool for searching text inside files and directories.
Basic search
rg "pattern"
Search recursively from the current directory.
rg "hello"
Search for hello in files below the current directory.
Search a specific directory
rg "pattern" src/
Search a specific file
rg "pattern" file.txt
Case-insensitive search
rg -i "pattern"
rg -i "hello"
Matches:
hello
Hello
HELLO
Match whole words
rg -w "word"
Matches word but not:
words
password
wording
Show line numbers
rg -n "pattern"
-n is usually enabled by default when output goes to the terminal.
Show only filenames
rg -l "pattern"
Useful for finding which files contain a match.
Show files without matches
rg -L "pattern"
Count matches
rg -c "pattern"
Example:
rg -c "TODO" src/
Search specific file types
rg "pattern" -t js
rg "pattern" -t ts
rg "pattern" -t py
List supported types:
rg --type-list
Search by file extension
rg "pattern" -g "*.ts"
rg "pattern" -g "*.css"
Exclude files
rg "pattern" -g '!*.min.js'
Exclude a directory:
rg "pattern" -g '!node_modules'
Search hidden files
By default, rg skips hidden files.
rg --hidden "pattern"
Search hidden files and ignored files
rg --no-ignore "pattern"
Combine them:
rg --hidden --no-ignore "pattern"
Search only the current directory
rg --max-depth 1 "pattern"
Search with regular expressions
rg supports regular expressions.
rg "foo|bar"
rg "user_[0-9]+"
Literal search:
rg -F "foo.bar"
-F disables regex interpretation.
Search for exact text
rg -F "foo.bar"
Useful when the search contains regex characters such as:
.
*
+
?
[
]
(
)
Invert matches
Find lines that don’t match:
rg -v "pattern"
Context around matches
Show lines before a match:
rg -B 2 "pattern"
Show lines after a match:
rg -A 2 "pattern"
Show both:
rg -C 2 "pattern"
Search filenames
rg --files
List files known to rg.
Filter them:
rg --files | rg '\.ts$'
Search Git-tracked files
rg automatically respects .gitignore.
rg "pattern"
To ignore Git’s ignore rules:
rg --no-ignore "pattern"
Search from the parent directory
rg "pattern" ..
Search multiple directories
rg "pattern" src/ tests/
Replace text
rg itself does not modify files.
A common workflow is:
rg "old" .
Then use another tool for replacement, such as sed or perl.
For example:
rg -l "old" . | xargs sed -i 's/old/new/g'
Be careful with bulk replacements.
Useful options
| Option | Meaning |
|---|---|
-i |
Case-insensitive |
-w |
Whole-word match |
-F |
Fixed string, no regex |
-v |
Invert match |
-l |
Show matching filenames |
-L |
Show non-matching filenames |
-c |
Count matches per file |
-n |
Show line numbers |
-A N |
Show N lines after |
-B N |
Show N lines before |
-C N |
Show N lines of context |
-g |
Glob filter |
-t |
File type filter |
--hidden |
Include hidden files |
--no-ignore |
Don’t respect ignore files |
--files |
List searchable files |
--max-depth N |
Limit directory depth |
Common recipes
Find TODOs:
rg "TODO"
Find a function:
rg "function foo"
Find imports:
rg "^import "
Search TypeScript files:
rg "useState" -t ts -t tsx
Find files containing a string:
rg -l "DATABASE_URL"
Search case-insensitively:
rg -i "error"
Search an exact string:
rg -F "foo.bar()"
Search including hidden files:
rg --hidden "pattern"
List all files:
rg --files
rg vs grep
Traditional:
grep -R "pattern" .
With rg:
rg "pattern"
rg is generally faster and has convenient defaults for modern projects, including recursive searching and respecting .gitignore.
The essentials
rg "pattern" # search
rg -i "pattern" # case-insensitive
rg -F "text" # literal text
rg -w "word" # whole word
rg -l "pattern" # filenames only
rg -c "pattern" # count
rg -t ts "pattern" # file type
rg -g "*.ts" "pattern" # glob
rg --hidden "pattern" # include hidden files
rg --no-ignore "pattern" # include ignored files
rg --files # list files
rg -C 2 "pattern" # surrounding context