rg 命令和 grep 命令比较:Linux 文本搜索工具怎么选

rg 命令和 grep 命令比较:Linux 文本搜索工具怎么选 在 Linux 开发和运维工作中grep几乎是最常用的文本搜索工具之一。无论是分析日志、查找代码还是定位配置问题都经常会看到grep error app.log不过在现代开发环境中还有一个非常好用的工具——rgripgrep。相比 greprg 更适合在大型代码仓库中进行递归搜索。它不仅速度快而且默认会自动忽略.gitignore中指定的文件使用起来更加方便。本文对grep和rg做一个系统比较并结合实际开发场景说明什么时候应该使用它们。一、grep 是什么grep是 Linux/Unix 系统中经典的文本搜索工具名称来自Global Regular Expression Print它可以在文件中搜索匹配指定模式的文本。最基本的用法grep error app.log表示在app.log中搜索包含error的行。1. 忽略大小写grep -i error app.log例如ERROR connection failed Error: timeout error occurred都会被匹配。2. 显示行号grep -n error app.log输出类似123:ERROR connection failed 456:error occurred3. 递归搜索grep -r TODO .在当前目录以及所有子目录中搜索TODO。也可以使用grep -R TODO .4. 只显示文件名grep -rl TODO .输出类似src/main.c src/session.c src/utils.c5. 使用扩展正则表达式grep -E error|warning|failed app.log可以匹配error warning failed二、rg 是什么rg的全名是ripgrep。它是一个现代化的递归文本搜索工具使用 Rust 编写设计目标之一就是提供快速、高效的代码搜索能力。最简单的使用方式rg error在当前目录递归搜索error。与 grep 相比最大的特点是rg 默认就是递归搜索。不需要像 grep 一样写grep -r error .直接rg error即可。三、rg 安装方法与grep不同rg并不是 Linux 系统默认安装的基础工具。因此在实际工作中经常会遇到$ rg error bash: rg: command not found可以先使用下面的命令检查command -v rg如果没有任何输出说明当前环境没有安装rg。1. Ubuntu / DebianUbuntu 和 Debian 可以直接通过apt安装sudo apt update sudo apt install ripgrep如果当前已经是root用户apt update apt install ripgrep安装完成后检查rg --version例如ripgrep 14.x.x对于 Ubuntu/Debian Docker 镜像也可以apt-get update apt-get install -y ripgrep2. RHEL / CentOS / Rocky Linux / AlmaLinux较新的 RHEL 系发行版可以使用sudo dnf install ripgrep部分较老的系统可以使用sudo yum install ripgrep如果软件源中找不到ripgrep需要根据具体发行版启用相应的软件仓库或者使用其他安装方式。3. FedoraFedora 可以直接安装sudo dnf install ripgrep4. Arch LinuxArch Linuxsudo pacman -S ripgrep5. macOS如果已经安装 Homebrewbrew install ripgrep安装完成rg --version6. WindowsWindows 可以使用wingetwinget install BurntSushi.ripgrep.MSVC也可以使用 Chocolateychoco install ripgrep安装完成后在 PowerShell、CMD 或 VS Code Terminal 中执行rg --version7. Docker 容器在开发环境中经常会进入一个精简 Docker 容器docker exec -it mycontainer bash这类镜像通常不会预装rg。如果是 Ubuntu/Debian可以临时安装apt-get update apt-get install -y ripgrep不过需要注意直接在运行中的容器中安装容器删除或重新创建后通常会丢失。如果项目长期需要使用rg推荐直接加入 DockerfileRUN apt-get update \ apt-get install -y ripgrep \ rm -rf /var/lib/apt/lists/*然后重新构建镜像。8. 没有 root 权限在某些开发服务器或者公司内部服务器上可能没有sudo权限。这种情况下可以使用 ripgrep 提供的预编译二进制文件将rg放到用户自己的目录例如~/bin/rg然后chmod x ~/bin/rg将目录加入 PATHexport PATH$HOME/bin:$PATH如果希望每次登录都生效可以加入~/.bashrc例如export PATH$HOME/bin:$PATH然后source ~/.bashrc最后检查rg --version9. 推荐的安装方式环境推荐方式Ubuntu / Debianapt install ripgrepRHEL / Rocky / AlmaLinuxdnf install ripgrepFedoradnf install ripgrepArch Linuxpacman -S ripgrepmacOSbrew install ripgrepWindowswinget install BurntSushi.ripgrep.MSVCDocker加入 Dockerfile无 root 权限用户目录安装二进制安装完成以后统一使用下面的命令确认rg --version如果能够正常显示版本号就说明rg已经可以使用。注意grep基本属于 Linux/Unix 环境的标配而rg通常需要额外安装。因此在编写需要跨服务器、跨发行版运行的脚本时不应该默认假设rg一定存在。四、grep 和 rg 的基本命令对比功能greprg搜索文件grep error file.logrg error file.log当前目录递归搜索grep -r error .rg error忽略大小写grep -i errorrg -i error显示行号grep -n errorrg -n error显示文件名grep -l errorrg -l error排除匹配grep -v errorrg -v error文件类型过滤--include*.c-g *.c正则表达式支持支持默认递归否是默认遵循.gitignore否是默认跳过.git否是适合大型代码仓库一般非常适合Linux 默认安装是否五、rg 最大的优势默认递归搜索这是 rg 最明显的优势之一。假设项目目录project/ ├── src/ │ ├── main.c │ ├── session.c │ └── utils.c ├── include/ │ └── session.h ├── test/ │ └── test_session.c └── build/使用 grepgrep -r session_create .使用 rgrg session_create两者都可以完成任务。但是 rg 的命令更加简洁。六、rg 对 Git 项目更加友好这是 rg 相比 grep 一个非常实用的优势。假设项目中存在.git/ build/ node_modules/ src/执行grep -r FreeSWITCH .grep 可能会搜索.gitbuildnode_modules二进制文件临时文件搜索结果可能非常庞大。而rg FreeSWITCH默认会遵循.gitignore并跳过一些不适合搜索的内容。例如.gitignorebuild/ *.o *.log node_modules/那么 rg 默认不会搜索这些文件。对于软件开发人员来说这一点非常重要。七、rg 可以方便地按照文件类型搜索例如一个 C/C 项目rg session_create -g *.c只搜索.c文件。搜索 C 和 Crg session_create -g *.{c,cpp,h,hpp}也可以直接使用rg session_create -t c或者rg session_create -t cpp查看支持的文件类型rg --type-list例如可以看到c: *.c, *.h cpp: *.cc, *.cpp, *.cxx, *.h, *.hpp python: *.py rust: *.rs这对大型代码仓库非常方便。八、grep 如何实现类似功能grep 也可以过滤文件grep -r session_create . --include*.c搜索 C/Cgrep -r session_create . \ --include*.c \ --include*.cpp \ --include*.h \ --include*.hpp可以发现grep 当然也能完成这些工作但是命令通常更加复杂。九、rg 的性能为什么通常更好rg 的性能优势来自多个方面。1. Rust 实现ripgrep 使用 Rust 编写可以充分利用现代 CPU 和内存模型。2. 并行搜索rg 可以利用多个 CPU 核心并行处理文件。3. 更聪明的文件过滤rg 默认跳过.git .gitignore 中忽略的文件 二进制文件 部分隐藏目录因此它搜索的文件数量通常比grep -r少很多。4. 高效的正则表达式实现rg 使用高性能的正则表达式实现对于大量文本搜索通常具有较好的性能。因此在一个大型 Git 仓库中rg some_function通常比grep -r some_function .更加高效。不过实际性能取决于数据量、文件类型、磁盘、正则表达式复杂度等因素不能简单认为 rg 在所有场景下都一定更快。十、grep 的优势在哪里虽然 rg 很好用但这并不意味着 grep 已经过时。恰恰相反grep 仍然是 Linux 环境中非常重要的基础工具。1. 几乎所有 Linux 环境都有例如一个精简 Docker 镜像docker exec -it container bash里面可能只有grep sed awk cat却没有rg这时候 grep 就非常重要。2. 适合日志分析例如grep ERROR app.log结合管道cat app.log | grep ERROR或者grep ERROR app.log | grep SIP进一步grep ERROR app.log | grep SIP | grep 503这是非常经典的 Linux 使用方式。3. 适合 Shell 脚本例如if grep -q running status.txt; then echo Service is running fi这里-q表示静默执行只通过返回值判断是否匹配。这种用法在 Shell 脚本中非常常见。十一、rg 的一些非常实用的用法1. 搜索字符串rg connection failed2. 忽略大小写rg -i error3. 显示行号rg -n error4. 只显示文件名rg -l error5. 排除某个目录rg error -g !build/**6. 搜索特定文件rg TODO -g *.c7. 搜索多个关键词rg error|warning|failed8. 查看上下文这是分析代码和日志时非常有用的功能rg -C 3 connection failed表示显示匹配行前后各 3 行。也可以rg -B 3 connection failed只显示前 3 行。rg -A 3 connection failed只显示后 3 行。十二、grep 和 rg 的正则表达式两者都支持正则表达式。例如rg error|warning|failed匹配error warning failed匹配数字rg [0-9]匹配 SIP Responserg SIP/2.0 [45][0-9]{2}例如可以匹配SIP/2.0 404 Not Found SIP/2.0 486 Busy Here SIP/2.0 503 Service Unavailable对于经常分析 SIP、FreeSWITCH、OpenSIPS 日志的人来说这种搜索方式非常实用。十三、实际开发中的几个场景场景一在代码中找函数定义rg session_create如果只搜索 C/Crg session_create -g *.{c,cpp,h,hpp}场景二查找某个配置例如rg rtp_timeout可以快速找到整个项目中所有引用。场景三分析 FreeSWITCH 日志例如rg ERROR|WARNING freeswitch.log查看 SIP 503rg SIP/2.0 503 freeswitch.log查看某个 Call-IDrg abc123456789 freeswitch.log查看匹配内容上下文rg -C 10 abc123456789 freeswitch.log场景四搜索整个 Git 项目推荐rg function_name而不是grep -r function_name .因为 rg 默认会帮你处理很多不需要搜索的文件。十四、什么时候应该使用 grep如果你满足以下情况grep 依然是非常好的选择服务器环境非常精简没有安装 rg分析单个日志文件写 Shell 脚本处理管道输入需要保证脚本在各种 Unix/Linux 环境中兼容例如ps -ef | grep freeswitch这种简单场景完全没有必要换成 rg。十五、什么时候推荐使用 rg如果你主要做C/C 开发Python 开发Linux 项目开发Git 仓库代码搜索大型代码库搜索快速定位函数、变量、配置分析大量源码那么非常推荐使用rg尤其是rg keyword应该成为日常开发中的一个高频命令。十六、rg 并不是 grep 的完全替代品两者的设计目标并不完全相同。可以简单理解grep ↓ 通用文本过滤工具 ↓ 日志、管道、Shell、单文件搜索而rg ↓ 现代代码搜索工具 ↓ Git、源码、大型项目、递归搜索因此更合理的方式不是“以后全部用 rg不用 grep。”而是简单文本过滤使用 grep代码仓库搜索优先使用 rg。十七、推荐的使用组合对于 Linux 开发人员可以形成这样的习惯。单个日志文件grep ERROR app.logShell 管道ps -ef | grep freeswitch搜索整个代码仓库rg function_name搜索 C/C 代码rg function_name -g *.{c,cpp,h,hpp}搜索代码并查看上下文rg -C 5 function_name搜索特定目录rg function_name src/排除目录rg function_name -g !test/**十八、脚本中如何兼容没有 rg 的环境这是实际工作中很容易遇到的问题。如果一个脚本可能运行在不同的 Linux 服务器上不应该默认假设rg一定存在。可以进行检查if command -v rg /dev/null 21; then rg ERROR . else grep -r ERROR . fi这样有rg→ 使用rg没有rg→ 自动退回grep如果只是简单地判断工具是否存在也可以command -v rg十九、最终应该怎么选择可以简单理解文本搜索 │ ┌──────────┴──────────┐ │ │ 单个文件/日志 代码仓库 │ │ grep rg │ │ Shell / 管道 Git / 源码搜索使用 grepgrep ERROR app.logps -ef | grep freeswitchgrep -r TODO /opt/project使用 rgrg session_createrg SIP/2.0 503rg TODO -g *.{c,cpp,h,hpp}二十、总结grep和rg都是非常优秀的文本搜索工具但定位略有不同。grep 的优势Linux 基础工具几乎无处不在命令简单管道处理非常方便非常适合日志和 Shell 脚本兼容性好不需要额外安装rg 的优势默认递归搜索搜索速度通常更快默认遵循.gitignore对 Git 项目非常友好文件类型过滤方便上下文显示方便更适合大型代码仓库因此对于日常 Linux 开发可以记住一个简单原则日志 / 管道 / Shell ↓ grep 代码仓库 / Git / 大量源码 ↓ rg如果机器上没有rg先检查command -v rgUbuntu/Debiansudo apt install ripgrepRHEL/Fedorasudo dnf install ripgrepmacOSbrew install ripgrepWindowswinget install BurntSushi.ripgrep.MSVCDockerRUN apt-get update \ apt-get install -y ripgrep \ rm -rf /var/lib/apt/lists/*最终可以形成一个很实用的习惯能用 rg 快速搜索代码就用 rg需要兼容各种 Linux 环境、处理日志或 Shell 管道时grep 依然是首选。对于经常进行 C/C、FreeSWITCH、OpenSIPS、Python 等项目开发的工程师建议在个人开发环境中安装rg而在生产服务器上仍然熟悉并保留grep的使用习惯。这样既能享受 rg 高效的代码搜索能力也不会因为目标服务器没有安装 rg 而影响排障效率。