日常用 Linux 查日志、找代码、过滤文本时,grep 是你用得最多的命令之一。但很多人只会简单的 grep "keyword" file,其实配合几个常用选项和基础正则,能让你的搜索效率提升数倍。
这篇文章不会罗列所有参数,只讲新手最常用、最能解决实际问题的用法,看完就能直接用。
grep 的全称是 Global Regular Expression Print,作用很简单:在文件或输入流中,按你给的“模式”逐行匹配,把符合条件的行打印出来。
这个“模式”可以是普通字符串,也可以是正则表达式。
先记住这几个选项,日常 80% 的场景都够用了。
默认 grep 区分大小写,经常漏掉大写开头的关键词。
# 在文件中搜索 error,不区分大小写
grep -i "error" /var/log/syslog
找到匹配内容后,想知道在第几行,方便编辑。
# 显示匹配行及其行号
grep -n "TODO" *.py
想排除某些行时用这个,比如“找出所有不包含 success 的行”。
# 显示不包含 "200 OK" 的日志行
grep -v "200 OK" access.log
默认会打印整行,如果你只想要匹配到的关键字本身。
# 只提取出日志中的 IP 地址(示例)
echo "192.168.1.1 - - [10/Oct/2000:13:55:36 -0700]" | grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"
不需要看内容,只想知道有多少行匹配。
# 统计访问日志中 404 出现的次数
grep -c "404" access.log
在多个文件中搜索时,只想知道哪些文件包含该关键词。
# 找出当前目录下所有包含 "root" 的 .conf 文件
grep -l "root" *.conf
要在整个目录及其子目录中搜索。
# 在 /etc 目录下递归搜索包含 "password" 的文件
grep -r "password" /etc/
查日志时最有用,找到错误行后,通常需要看前后几行才能定位问题。
# 显示匹配行及后面 3 行
grep -A 3 "timeout" app.log
# 显示匹配行及前面 2 行
grep -B 2 "exception" error.log
# 显示匹配行前后各 2 行(最常用)
grep -C 2 "fatal" system.log
grep 默认支持“基本正则表达式(BRE)”,如果想用更简洁的扩展正则,加 -E 选项。
# 找出以 "start" 开头的行
grep "^start" file.txt
# 找出以 "." 结尾的行(注意 . 要转义)
grep "\.$" file.txt
# 找出空行
grep "^$" file.txt
# 匹配 a 开头、c 结尾,中间任意一个字符的行(abc, a1c, a-c 等)
grep "a.c" file.txt
代表前一个字符出现 0 次或多次。
# 匹配 g 后面跟 0 个或多个 o,再接 g(gg, gog, goog, goooog)
grep "go*g" file.txt
这是最常用的组合,代表“任意内容”。
# 匹配以 "begin" 开头,以 "end" 结尾,中间任意内容的行
grep "begin.*end" file.txt
匹配括号内任意一个字符。
# 匹配数字
grep "[0-9]" file.txt
# 匹配小写字母
grep "[a-z]" file.txt
# 匹配不是数字的字符(^ 在 [] 内表示取反)
grep "[^0-9]" file.txt
加上 -E 后,不用转义就能使用 +、?、|、() 这些符号。
和 * 类似,但要求前一个字符至少出现一次。
# 匹配至少一个 o(go, goo, gooo...)
grep -E "go+" file.txt
# 匹配 gd 或 god
grep -E "go?d" file.txt
# 匹配包含 error 或 warning 的行
grep -E "error|warning" file.txt
# 匹配 2 到 5 个 o
grep -E "o{2,5}" file.txt
# 匹配至少 2 个 o
grep -E "o{2,}" file.txt
# 在 syslog 中找 error,忽略大小写,显示前后 2 行
grep -i -C 2 "error" /var/log/syslog
场景 2:在代码中递归找 TODO 并显示文件名和行号grep -rn "TODO" /path/to/code/
grep "192.168.1.100" /var/log/nginx/access.log
场景 4:批量修改文件中的字符串(配合 xargs 和 sed)# 先找出所有包含 old_string 的文件,再传给 sed 替换
grep -rl "old_string" /path/to/dir | xargs sed -i 's/old_string/new_string/g'
- 先用
--color=auto 让匹配结果高亮,看着方便。可以在 ~/.bashrc 里加一行 alias grep='grep --color=auto',永久生效。 - 对大文件搜索时,配合
tail -f 看实时日志,或先 head/tail 截取一部分再 grep,避免卡顿。 - 不确定正则写得对不对时,先在小文件上试,不要直接在生产环境大文件上跑。
- 基本正则和扩展正则的区别主要在转义,新手建议直接用
grep -E,省得记哪些要转义。
grep 不需要背完所有参数,先把上面这些用熟,遇到复杂需求再查文档就够了。