飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • 基础入门

    • Linux 命令概述与环境准备
    • 文件与目录操作(上):ls、cd、pwd
    • 文件与目录操作(下):cat、touch、mkdir、rm、cp、mv
    • 获取帮助与基础工具:man、help、clear、exit、sudo
  • 文件权限

    • 文件权限管理:chmod、chown
  • 系统与监控

    • 进程管理与系统监控:ps、top、kill、df、du、free
    • 用户与环境:whoami、id、env、echo、history
  • 网络命令

    • 网络诊断(上):ping、curl、wget
    • 网络诊断(下):netstat、ss、ip
    • 网络抓包与高级工具:traceroute、tcpdump、nc
    • DNS 与防火墙:nslookup、dig、iptables
  • 文本处理

    • 文本搜索:grep
    • 文本处理(上):awk
    • 文本处理(下):sed
    • 文本排序与统计:sort、uniq、wc
    • 文件查看与查找:head、tail、cut、find
    • 归档压缩与管道组合:tar、gzip、xargs
  • 开发工具

    • 开发工具链(上):gcc、make
    • 开发工具链(下):gdb、time
    • 版本控制:git
    • 远程操作:ssh、scp
    • 编辑器:vim、nano
  • Shell 编程

    • Shell 编程基础(上):变量、管道、重定向
    • Shell 编程基础(下):条件、循环、函数
  • 综合实战

    • 综合实战:日志分析

文本搜索:grep

grep 核心定位

grep(Global Regular Expression Print)是 Linux 文本搜索的核心工具,基于正则表达式匹配,配合管道 | 可以处理任意命令的输出。

基础用法

# 在文件中搜索包含 "error" 的行
grep "error" log.txt

# 忽略大小写(-i ignore-case)
grep -i "error" log.txt

# 显示行号(-n line-number)
grep -n "error" log.txt

# 显示不匹配的行(-v invert-match)
grep -v "error" log.txt

# 只显示匹配的文件名(-l files-with-matches)
grep -l "error" *.log

# 显示匹配次数(-c count)
grep -c "error" log.txt

# 显示匹配上下文(-C context)
grep -C 2 "error" log.txt    # 显示匹配行及前后 2 行

正则表达式基础

基本正则(BRE,默认)

元字符含义示例
.任意单个字符g.p 匹配 gap, gbp, gcp
*前一个字符 0 次或多次go*d 匹配 gd, god, good
^行首^error 匹配行首的 error
$行尾error$ 匹配行尾的 error
[]字符类[aeiou] 匹配任意元音
[^]反向字符类[^0-9] 匹配非数字

扩展正则(ERE,-E)

# 使用扩展正则(-E extended-regexp)
grep -E "go+d" file.txt     # + 表示 1 次或多次
grep -E "go?d" file.txt     # ? 表示 0 次或 1 次
grep -E "good|bad" file.txt # | 表示或
grep -E "(go)+" file.txt    # () 分组
元字符含义示例
+1 次或多次go+d 匹配 god, good
?0 次或 1 次go?d 匹配 gd, god
``或
()分组(ab)+ 匹配 ab, abab
{n}恰好 n 次a{3} 匹配 aaa
{n,}至少 n 次a{2,} 匹配 aa, aaa
{n,m}n 到 m 次a{1,3} 匹配 a, aa, aaa

实用选项组合

# 递归搜索目录(-r recursive)
grep -r "error" /var/log/

# 递归搜索并显示文件名(-H with-filename)
grep -rH "error" /var/log/

# 递归搜索,排除二进制文件(-I ignore-binary)
grep -rI "error" /var/log/

# 搜索时排除特定文件(--exclude)
grep -r "error" /var/log/ --exclude="*.gz"

# 搜索时排除特定目录(--exclude-dir)
grep -r "error" /var/log/ --exclude-dir="archive"

# 只匹配整个单词(-w word-regexp)
grep -w "error" file.txt    # 匹配 "error" 但不匹配 "errors"

# 只匹配整行(-x line-regexp)
grep -x "error" file.txt    # 只匹配单独一行的 "error"

# 限制匹配数量(-m max-count)
grep -m 5 "error" file.txt  # 只显示前 5 个匹配

# 静默模式(-q quiet),用于脚本判断
if grep -q "error" log.txt; then
    echo "发现错误"
fi

管道组合实战

场景 1:查找日志中的错误并统计

# 查找包含 ERROR 的行
grep "ERROR" app.log

# 统计 ERROR 出现次数
grep -c "ERROR" app.log

# 查找 ERROR 并显示前后 3 行上下文
grep -C 3 "ERROR" app.log

# 查找所有日志文件中的 ERROR
grep -r "ERROR" /var/log/

场景 2:过滤进程列表

# 查找 nginx 进程
ps aux | grep nginx

# 排除 grep 自身(grep [n]ginx 技巧)
ps aux | grep [n]ginx

# 或更优雅的方式
ps aux | grep nginx | grep -v grep

场景 3:查找代码中的函数定义

# 查找 C 语言中的 main 函数定义
grep -n "^int main" *.c

# 查找 Python 中的函数定义
grep -n "^def " *.py

# 查找包含 TODO 或 FIXME 的注释
grep -rn "TODO\|FIXME" src/

grep 家族

命令特点适用场景
grep基本正则通用搜索
egrep扩展正则(等同于 grep -E)复杂正则
fgrep固定字符串(等同于 grep -F)搜索含特殊字符的字符串
rg (ripgrep)极速递归搜索大型代码库搜索
ag (The Silver Searcher)快速搜索,自动忽略版本控制代码搜索
# ripgrep 示例(需安装)
rg "error" /var/log/          # 递归搜索,自动忽略隐藏文件
rg -t py "def main"           # 只在 Python 文件中搜索
rg -C 3 "error" app.log       # 显示上下文

本篇小结

  • grep "pattern" file:基础文本搜索,基于正则表达式
  • -i 忽略大小写,-n 显示行号,-v 反向匹配,-c 计数
  • -r 递归搜索目录,--exclude 排除文件,--exclude-dir 排除目录
  • -w 匹配整个单词,-x 匹配整行,-q 静默模式(脚本判断)
  • 基本正则:. * ^ $ [];扩展正则(-E):+ ? | () {n,m}
  • 管道组合:ps aux | grep nginx | grep -v grep
  • egrep = grep -E,fgrep = grep -F,rg 是现代化替代

动手实践

  1. 基础搜索练习:

    # 创建一个测试文件
    cat > test.txt
    apple
    banana
    Application
    apply
    pine
    pineapple
    # Ctrl+D
    
    grep "app" test.txt
    grep -i "app" test.txt
    grep -n "app" test.txt
    grep -w "app" test.txt
    grep -v "app" test.txt
    
  2. 正则表达式练习:

    grep "^a" test.txt        # 以 a 开头
    grep "e$" test.txt        # 以 e 结尾
    grep "a.e" test.txt       # a 和 e 中间一个字符
    grep -E "a+p" test.txt    # 1 个或多个 a 后跟 p
    
  3. 进程过滤练习:

    ps aux | grep bash
    ps aux | grep [b]ash      # 排除 grep 自身
    
  4. 递归搜索练习:

    grep -r "TODO" /usr/share/doc/ --exclude-dir=".git"
    
  5. 统计练习:

    grep -c "error" /var/log/syslog
    grep -r -c "error" /var/log/
    
  6. 思考:为什么 ps aux | grep nginx | grep -v grep 能排除 grep 自身?如果写成 ps aux | grep -v grep | grep nginx,结果会有什么不同?

下一页
文本处理(上):awk