grep 命令
目录
grep 是 Linux / macOS 终端里最常用的文本搜索命令,用来在文件中查找包含指定内容的行。平时查日志、搜配置、看源码、筛命令输出,几乎都会用到它。
注:用到了这个命令想写一长段,写了一小段写了几天都写不动,后交由 gpt5.4 扩写,未经人工校对,可能存在错误,仅供参考。
基本语法
grep [选项] "模式" 文件名
例如:
grep "123" 333.txt
含义:查找 333.txt 中所有包含 123 的行。
如果要从命令输出里继续筛选,也可以这样写:
ps aux | grep nginx
含义:先列出进程,再从结果里找出包含 nginx 的行。
常用参数速查
grep -i "123" 333.txt
忽略大小写(abc 和 ABC 都能匹配)。
grep -n "123" 333.txt
显示行号,便于定位。
grep -c "123" 333.txt
只统计匹配行数,不显示具体内容。
grep -v "123" 333.txt
反向匹配:显示不包含 123 的行。
grep -l "123" *.txt
只列出“包含匹配内容”的文件名。
grep -L "123" *.txt
只列出“不包含匹配内容”的文件名。
grep -o "123" 333.txt
只输出匹配到的部分,不输出整行。
grep -w "cat" words.txt
按“完整单词”匹配,比如会匹配 cat,但不会匹配 category。
grep -x "hello" words.txt
整行完全匹配,只有这一行内容刚好等于 hello 才算命中。
递归搜索目录
grep -r "123" ./mydir
在 mydir 目录及其子目录中递归查找。
-r 与 -R 都用于递归搜索:
-r:递归目录。-R:递归目录,并会跟随符号链接(不同系统实现细节可能略有差异)。
经常会和 -n 一起使用:
grep -rn "database" ./project
这样可以同时看到文件路径、行号和匹配内容。
只查指定类型的文件
项目里文件很多时,直接递归搜索往往会把无关内容也带出来,这时可以限制文件范围。
grep -rn "main" . --include="*.rs"
只在 .rs 文件中查找。
grep -rn "debug" . --exclude="*.log"
排除 .log 文件。
grep -rn "TODO" . --exclude-dir="node_modules"
排除某个目录。
这几个参数在大项目里很实用,不然结果会很杂。
显示匹配行前后的上下文
排查日志或读代码时,只看一行通常不够,这时可以带上前后文。
grep -nA 3 "Exception" app.log
显示匹配行以及后面 3 行。
grep -nB 2 "Exception" app.log
显示匹配行以及前面 2 行。
grep -nC 2 "Exception" app.log
显示匹配行前后各 2 行。
其中:
-A= after,后面几行。-B= before,前面几行。-C= context,前后几行。
grep 与正则表达式
grep 最强的地方之一,就是可以配合正则表达式使用。
基础示例
grep "^root" /etc/passwd
查找以 root 开头的行。
grep "sh$" /etc/passwd
查找以 sh 结尾的行。
grep "[0-9]" data.txt
查找包含数字的行。
grep "\.jpg$" filelist.txt
查找以 .jpg 结尾的文件名。这里的 . 需要转义,因为在正则里点号有特殊含义。
扩展正则
如果想用更方便的正则语法,可以加 -E:
grep -E "foo|bar" test.txt
匹配 foo 或 bar。
grep -E "[0-9]{3}" test.txt
匹配连续 3 位数字。
常见写法:
^abc:以abc开头。xyz$:以xyz结尾。.:任意单个字符。[abc]:a、b、c其中一个。[0-9]:任意一位数字。foo|bar:匹配foo或bar,通常配合-E。
实战示例
- 在项目中查找包含
TODO的代码行:
grep -rn "TODO" .
- 查找日志中的
error(忽略大小写):
grep -i "error" app.log
- 统计 Nginx 日志中
404出现的行数:
grep -c " 404 " access.log
- 只看配置文件里“非注释行”:
grep -v "^#" nginx.conf
- 过滤空行和注释行:
grep -Ev "^#|^$" nginx.conf
- 在 Markdown 文件里找二级标题:
grep "^## " notes.md
- 只提取日志里的 IP 地址片段(简单匹配示例):
grep -Eo "[0-9]{1,3}(\.[0-9]{1,3}){3}" access.log
这里用了:
-E:启用扩展正则。-o:只输出匹配到的内容。
和管道一起使用
grep 很常见的一种用法,不是直接查文件,而是接在别的命令后面做筛选。
history | grep git
从历史命令中找出包含 git 的记录。
ls -la | grep "\.md$"
从 ls 输出里找出 Markdown 文件。
cat app.log | grep ERROR
这个写法可以用,但如果是直接查文件,通常更推荐:
grep ERROR app.log
少一个管道,写法也更直接。
搜进程时的一个小坑
很多人会这样查进程:
ps aux | grep nginx
问题是它通常也会把 grep nginx 这一行自己匹配出来。
常见写法:
ps aux | grep "[n]ginx"
这样既能匹配 nginx 进程,又不会把当前这条 grep 命令本身匹配进去。
返回值
grep 不只是看输出,还常被放进脚本里判断条件。
- 找到匹配内容时,返回值是
0。 - 没找到时,返回值是
1。 - 执行出错时,返回值大于
1。
例如:
grep -q "ready" app.log
echo $?
其中 -q 表示安静模式,不输出内容,只看是否匹配成功。
脚本里经常这样写:
if grep -q "ready" app.log; then
echo "service is ready"
fi常见组合
grep -rin "keyword" ./src
-r:递归-i:忽略大小写-n:显示行号
这是日常开发里非常高频的一组参数。
小提示
- 模式里有空格时记得加引号,例如
"hello world"。 - 用正则表达式时,优先单引号防止 shell 提前展开,例如:
grep -E 'foo|bar' file.txt。 - 文件很多时,建议搭配
--include、--exclude精准过滤文件范围。 - 只判断“有没有”时,用
-q比直接看输出更适合脚本。 - 搜代码仓库时,
grep能用,但如果项目很大,rg通常更快。
示例:
grep -rn "main" . --include="*.rs" --exclude-dir="target"总结
grep 的核心就是:在文本中按“模式”筛选行。先记住 -i -n -v -c -r 这些最常用参数,再补上 -E、-o、-A/-B/-C 这些进阶选项,日常查日志、找配置、搜源码基本就够用了。
如果只是普通文本搜索,先从最简单的命令开始;如果搜索条件变复杂,再逐步加上正则和过滤参数。这样最不容易写乱。
系列:note
该系列自动来自分类: note