rg Tutorial: Why Many Developers Use ripgrep Instead of grep
While using GitHub Copilot recently, I kept noticing that it reached for rg when it needed fast text and code search. That was a good reason to revisit the practical difference between rg and grep.
When people need to search for a string on Linux, the first command that comes to mind is still often grep. But if you regularly search through source trees, filter by file type, skip node_modules, or avoid noise from .git, rg which is the command for ripgrep is usually the more convenient choice.
grep is still useful, especially in shell pipelines, when reading from standard input, and when you need maximum compatibility with older scripts. But for the common developer task of searching through code or logs inside a project directory, rg is often faster, cleaner, and better tuned by default.
This article does one thing: explain rg with runnable commands and compare it directly to grep.
1. What rg is and how it relates to grep
rg is the command name for ripgrep, a text-searching tool.
Its core goal is the same as grep: find matching text. The difference is that the default behavior is much more convenient for modern code-search workflows.
Key defaults that stand out:
rgsearches directories recursively by defaultrgrespects.gitignoreby defaultrgskips a lot of irrelevant hidden or binary content by defaultrgoutput is more immediately useful for code search, with clear file names and line numbers- In many source repositories,
rgis faster thangrep -R
So a practical mental model is:
grepis more traditional and universalrgfeels like a code-search tool with better defaults already enabled
2. Install rg
Installation depends on your OS, but these are the common commands.
1. Debian / Ubuntu
apt update
apt install ripgrep -y
2. CentOS / Rocky / AlmaLinux
yum install ripgrep -y
If the package is not available, enable EPEL first and then install it.
3. Arch Linux
pacman -S ripgrep
4. macOS
brew install ripgrep
After installation, verify it:
rg --version
3. The most useful rg patterns
The easiest way to learn rg is to look at a few high-frequency cases.
1. Recursively search for a string in the current directory
If you want to find TODO anywhere in the current project:
rg "TODO"
The typical grep equivalent is:
grep -R "TODO" .
This is the first major difference: rg is recursive by default, while grep usually needs -R.
2. Show line numbers
rg prints line numbers by default in most normal search output:
rg "timeout"
With grep, people usually write:
grep -Rn "timeout" .
3. Search only specific file types
To search for def main only in Python files:
rg -n -g '*.py' 'def main'
With grep, this is usually a bit more verbose:
grep -Rns --include='*.py' 'def main' .
If you frequently filter by extension, rg -g is usually more ergonomic than grep --include.
4. Case-insensitive search
rg -i "error"
Equivalent grep:
grep -Rni "error" .
5. Show surrounding context
To display 2 lines before and after a match:
rg -C 2 "panic"
Equivalent grep:
grep -RnC 2 "panic" .
6. Search hidden or ignored files
By default, rg respects .gitignore, which is usually what you want. But sometimes you need to search everything.
rg --hidden --no-ignore "API_KEY"
If you only want hidden files but still want ignore rules:
rg --hidden "API_KEY"
This is one of the nicest parts of rg: quiet by default, wider only when you explicitly ask for it.
4. Direct comparison: rg vs grep
Here is a practical side-by-side comparison for common development work.
| Scenario | grep | rg |
|---|---|---|
| Recursive directory search | Needs -R |
Recursive by default |
.gitignore support |
Not automatic | Automatic by default |
| Searching code repositories | Works, but usually more verbose | Better default experience |
| Searching one file or stdin | Very common | Also supported |
| Speed in large repos | Often slower | Often faster |
| Compatibility in old scripts | Stronger | Less universal than grep |
If you want a one-line rule of thumb:
- Use
rgfirst for source repositories - Keep using
grepfor maximum script compatibility or simple stdin filtering
5. A more realistic example
Suppose you inherit a Python project and want to find every place related to requests timeouts.
With rg:
rg -n -g '*.py' 'timeout|read_timeout|connect_timeout'
If you also want to exclude the test directory:
rg -n -g '*.py' -g '!tests/**' 'timeout|read_timeout|connect_timeout'
You can do the same with grep, but it usually pushes you toward longer flag combinations, find, or xargs.
Or imagine scanning logs for HTTP 500 responses:
rg -n -C 2 ' 500 |HTTP/1.1" 500' logs/
This kind of workflow, where you want recursion, context lines, and good path filtering together, is where rg usually feels best.
6. How to verify that rg is faster on your machine
Performance depends on the machine and the directory being searched, so the best approach is to benchmark on your own project.
For example:
time grep -R "function" . > /tmp/grep-result.txt
time rg "function" > /tmp/rg-result.txt
Check two things:
- Total runtime
- Whether the output actually focuses on the files you care about
In many repositories, rg is not only faster but also cleaner because it ignores a lot of irrelevant content by default.
7. Common issues
1. rg: command not found
That simply means ripgrep is not installed yet. Install it with one of the commands above.
2. Why didn’t rg find a string that I know exists?
Check these first:
- The file may be ignored by
.gitignore - The file may be hidden
- The target may be treated as binary
Try widening the search:
rg --hidden --no-ignore "keyword"
3. Can grep replace rg completely?
Partly, yes, but the experience is different.
If you are just grepping one file or filtering standard output in a pipeline, grep is perfectly fine. If you spend a lot of time searching through project directories, logs, and config files, rg is usually more efficient.
8. Summary
grep is not obsolete. It is still one of the core tools in the Unix toolbox. But if your main task is quickly searching through code, config, and logs inside project directories, rg is usually the more modern and better-defaulted choice.
In practice, a simple workflow works well:
- Use
rgfirst for project-wide searches - Keep
grepfor legacy scripts or standard-input filtering - Add
--hiddenor--no-ignoreonly when you need wider coverage
That split is usually the most time-efficient.
- 原文作者:春江暮客
- 原文链接:https://www.bobobk.com/en/rg-vs-grep.html
- 版权声明:本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。