【Linux从入门到精通】第27篇:文本处理三剑客(上)——grep 正则表达式实战

目录

一、引言:从"找东西"说起

二、grep基础:从简单搜索开始

[2.1 基本语法](#2.1 基本语法)

[2.2 常用基础选项](#2.2 常用基础选项)

[2.3 管道中的grep](#2.3 管道中的grep)

三、正则表达式:从"搜文字"到"搜模式"

[3.1 两种正则标准:BRE与ERE](#3.1 两种正则标准:BRE与ERE)

[3.2 基础元字符](#3.2 基础元字符)

[3.3 扩展正则(grep -E)新增元字符](#3.3 扩展正则(grep -E)新增元字符)

[3.4 常用字符类](#3.4 常用字符类)

四、实战一:查找邮箱地址

五、实战二:查找IP地址

六、实战三:查找电话号码

七、grep的高级功能

[7.1 上下文控制:找到后看周围内容](#7.1 上下文控制:找到后看周围内容)

[7.2 递归搜索:在整个目录中查找](#7.2 递归搜索:在整个目录中查找)

[7.3 统计匹配数量](#7.3 统计匹配数量)

[7.4 精确匹配控制](#7.4 精确匹配控制)

八、grep实战组合技

[8.1 实时监控特定错误](#8.1 实时监控特定错误)

[8.2 排除注释和空行(查看有效配置)](#8.2 排除注释和空行(查看有效配置))

[8.3 批量在所有配置文件中搜索](#8.3 批量在所有配置文件中搜索)

九、本篇小结

动手练习

十、下篇预告


一、引言:从"找东西"说起

在Windows或macOS下,你习惯按Ctrl+F在文档中搜索关键词。在Linux命令行下,这个操作对应的命令就是grep

grep的名字来源于一个古老的编辑器命令:g/re/p(global / regular expression / print),意思是"全局搜索正则表达式并打印匹配行"。从名字就能看出它的核心能力:

  1. 搜索:在一堆文本中找到目标

  2. 正则表达式:不只是搜"固定文字",还能搜"符合某种模式"的文字

  3. 打印:把匹配的行输出给你看

在运维和开发工作中,grep的出现频率极高------查日志、找配置、过滤进程、筛选数据,几乎无处不用。

二、grep基础:从简单搜索开始

2.1 基本语法

bash

复制代码
grep [选项] '搜索模式' 文件名

最简单的用法

bash

复制代码
grep 'error' /var/log/syslog         # 在日志中找包含error的行
grep 'root' /etc/passwd              # 查看root用户信息
ps aux | grep nginx                   # 查看nginx相关进程

2.2 常用基础选项

选项 含义 示例
-i 忽略大小写 grep -i 'Error' app.log
-v 反向匹配(排除) grep -v '^#' nginx.conf(排除注释行)
-n 显示行号 grep -n 'error' app.log
-c 只显示匹配行数量 grep -c '404' access.log
-w 匹配整个单词 grep -w 'at' file(不会匹配cat/ate)
-r 递归搜索目录 grep -r 'TODO' ./src/
-l 只输出文件名 grep -rl 'config' /etc/
--color 高亮匹配内容 grep --color 'error' app.log

2.3 管道中的grep

grep最常用的姿势不是直接搜文件,而是作为管道中的过滤器

bash

复制代码
# 查看所有监听端口中的80端口
ss -tlnp | grep :80

# 查看ERROR级别的日志并高亮
tail -f /var/log/app.log | grep --color -i error

# 查看nginx进程(排除grep自身)
ps aux | grep nginx | grep -v grep

小技巧ps aux | grep nginx | grep -v grep这条命令经常出现。另一种写法是ps aux | grep [n]ginx------方括号让grep匹配nginx但grep进程本身的命令行是grep [n]ginx,不匹配,从而省掉一个grep -v

三、正则表达式:从"搜文字"到"搜模式"

grep真正的威力来自正则表达式。正则表达式是一种描述字符串模式的语法,让你能搜索"形如邮箱""形如IP地址"的内容,而不是具体文字。

3.1 两种正则标准:BRE与ERE

Linux中的grep支持两种正则语法:

标准 全称 grep命令 特点
BRE Basic Regular Expression grep(默认) 老式标准,部分元字符需要转义
ERE Extended Regular Expression grep -Eegrep 现代标准,元字符直接使用

选择建议始终使用grep -E(扩展正则) 。BRE需要频繁加反斜杠转义,如\(\)\{\},可读性差且容易出错。除非要兼容极老的Unix系统,否则直接用ERE。

3.2 基础元字符

元字符 含义 示例 匹配结果
. 匹配任意单个字符 h.t hat, hit, h3t
* 前一个字符重复0次或多次 ab*c ac, abc, abbc
^ 行首 ^error 以error开头的行
$ 行尾 error$ 以error结尾的行
[] 字符集合中的任意一个 [Bb]ash Bash, bash
[^] 不在集合中的任意一个 [^0-9] 非数字字符
\ 转义字符 \. 匹配真正的点号

3.3 扩展正则(grep -E)新增元字符

元字符 含义 示例
+ 前一个字符重复1次或多次 ab+c → abc, abbc(不匹配ac)
? 前一个字符重复0次或1次 colou?r → color, colour
` ` 或(分支)
() 分组 `(error
{n} 前一个字符重复恰好n次 [0-9]{3} → 三位数字
{n,} 前一个字符重复n次及以上 [0-9]{3,} → 至少三位数字
{n,m} 前一个字符重复n到m次 [0-9]{2,4} → 两到四位数字

3.4 常用字符类

写法 含义 等价写法
[0-9] 数字 [[:digit:]]
[a-zA-Z] 字母 [[:alpha:]]
[a-zA-Z0-9] 字母数字 [[:alnum:]]
[ \t] 空白字符 [[:space:]]
[A-Z] 大写字母 [[:upper:]]
[a-z] 小写字母 [[:lower:]]

POSIX字符类的优势[[:digit:]][0-9]更规范,且在不同locale下行为一致。在写复杂脚本时推荐使用。

四、实战一:查找邮箱地址

bash

复制代码
grep -E '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' file.txt

模式拆解

部分 含义
[a-zA-Z0-9._%+-]+ 用户名部分:字母/数字/特殊符号,至少1个字符
@ 必须的@符号
[a-zA-Z0-9.-]+ 域名部分:字母/数字/点/短横线,至少1个字符
\. 转义的点号(分隔域名和后缀)
[a-zA-Z]{2,} 顶级域名:至少2个字母

验证:

bash

复制代码
echo "联系admin@example.com或support@my-site.org获取帮助" | \
    grep -E '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'

五、实战二:查找IP地址

IPv4地址由4组0-255的数字组成:

bash

复制代码
grep -E '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' file.txt

逐组拆解

部分 匹配范围
25[0-5] 250-255
2[0-4][0-9] 200-249
[01]?[0-9][0-9]? 0-199(灵活处理前导零)
\. 点号分隔符
{3} 前三组重复3次
最后重复一组 第四组数字(结束)

边界控制说明 :上述模式会把992.168.1.100这样的字符串从第2位开始截取匹配。如果需要精确校验整行内容(拒绝嵌入数字的IP),可以加\<\>单词边界锚定,或用grep -w。一般grep从日志中提取IP时,周围有限定符号(空格、引号等),前述模式已足够实用。

六、实战三:查找电话号码

匹配中国手机号码(1开头的11位数字):

bash

复制代码
grep -E '\b1[3-9][0-9]{9}\b' file.txt

模式拆解

  • \b:单词边界,防止匹配长数字串中间的部分

  • 1:开头必须是1

  • [3-9]:第二位是3-9(覆盖所有运营商的号段)

  • [0-9]{9}:后面接9位数字

  • \b:单词边界结束

七、grep的高级功能

7.1 上下文控制:找到后看周围内容

匹配到目标行后,往往需要看周围的几行来理解上下文。

bash

复制代码
# 查看匹配行及之后3行(找错误日志时特别有用,看错误之后发生了什么)
grep -A 3 'FATAL' app.log

# 查看匹配行及之前2行(查看错误发生前系统在做什么)
grep -B 2 'FATAL' app.log

# 查看匹配行前后各5行(最常用,全面了解上下文)
grep -C 5 'FATAL' app.log

7.2 递归搜索:在整个目录中查找

bash

复制代码
# 在当前目录及所有子目录的.sh文件中搜索
grep -r 'TODO' . --include="*.sh"

# 排除某些目录
grep -r 'function' ./src/ --exclude-dir={node_modules,vendor}

# 只列出包含匹配的文件名
grep -rl 'config' /etc/

7.3 统计匹配数量

bash

复制代码
# 统计nginx日志中404的出现次数
grep -c ' 404 ' /var/log/nginx/access.log

# 统计每个IP发起请求的次数(用到后续文章的工具)
grep -oE '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' access.log | sort | uniq -c | sort -rn | head

7.4 精确匹配控制

bash

复制代码
# 只输出匹配的内容(而不是整行)
echo "Server IP: 192.168.1.1" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'

# 只显示匹配的文件名
grep -rl 'ERROR' /var/log/

-o选项的妙用 :当你不需要看整行、只想要精确提取数据片段时,-o配合正则能高效抽取结构化数据,如从日志中提取所有IP地址。

八、grep实战组合技

8.1 实时监控特定错误

bash

复制代码
tail -f /var/log/nginx/error.log | grep --color -E '500|502|503|504'

8.2 排除注释和空行(查看有效配置)

bash

复制代码
grep -v '^\s*#' nginx.conf | grep -v '^\s*$'

8.3 批量在所有配置文件中搜索

bash

复制代码
grep -rE 'server_name\s+example\.com' /etc/nginx/ --include="*.conf"

九、本篇小结

grep核心能力:搜索文本 + 正则模式匹配 + 管道过滤。

选项速查

选项 作用
-E 使用扩展正则(推荐)
-i 忽略大小写
-v 反向匹配
-n 显示行号
-c 统计匹配数量
-A/-B/-C N 显示匹配行前后N行
-r 递归搜索目录
-o 只输出匹配部分
-l 只输出文件名
-w 整词匹配

正则核心元字符

字符 作用 示例
. 任意单字符 h.t
* 0~n次 ab*c
+ 1~n次 ab+c
? 0~1次 colou?r
^ / $ 行首 / 行尾 ^error / error$
[] 字符集合 [0-9]
() 分组 `(error
{n,m} 重复n~m次 [0-9]{2,4}

动手练习

bash

复制代码
# 1. 在/etc/passwd中查找所有使用/bin/bash的用户
grep '/bin/bash' /etc/passwd

# 2. 统计nginx日志中404错误的数量
grep -c ' 404 ' /var/log/nginx/access.log

# 3. 查看sshd配置(排除注释和空行)
grep -vE '^\s*(#|$)' /etc/ssh/sshd_config

# 4. 从日志中提取所有IP地址
grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head

# 5. 在shell脚本中搜索所有函数定义
grep -rnE '^[a-zA-Z_][a-zA-Z0-9_]*\s*\(\)' ~/scripts/

十、下篇预告

grep擅长查找 文本,但找到之后如果要做替换(比如批量修改配置文件中的IP地址),grep就无能为力了。

下一篇我们将学习三剑客的第二位------sed流编辑器,它能以非交互的方式对文本进行查找、替换、删除、插入操作。你将学会用一条命令批量修改上百个文件中的特定内容------这就是命令行效率的终极体现。


延伸思考 : 如果你用的是grep -P,可以开启Perl兼容正则(PCRE),支持\d(数字)、\w(单词字符)、\s(空白)等快捷符号,以及环视断言(lookahead/lookbehind)。但要注意-P选项不是所有系统都有(macOS默认grep不支持),在编写需要跨平台运行的脚本时建议优先使用-E方式。

本回答由 AI 生成,内容仅供参考,请仔细甄别。

相关推荐
码到成功>_<1 小时前
Linux中grep命令使用说明
linux
minji...1 小时前
Linux 网络套接字编程(六)TCP的通信是全双工的,自定义协议的定制,序列化和反序列化
linux·运维·服务器·网络·c++
小王C语言1 小时前
【linux进程信号】————产生信号:signal自定义信号处理动作(自定义捕捉)、前后台进程、产生信号的方式(函数、软条件、硬件异常)....等等
运维·服务器·前端
晚风予卿云月2 小时前
【linux】僵尸进程与孤儿进程
linux·运维·服务器
hhb_6182 小时前
Tcl脚本自动化运维实操落地案例详解
运维·网络·自动化
故事还在继续吗2 小时前
Linux cgroup 使用指南:从原理到实践
linux·运维·服务器
csdn2015_2 小时前
lambdaQuery 加 or
java·linux·服务器
ℳ₯㎕ddzོꦿ࿐2 小时前
实战:在 Linux 系统用 Docker-Compose 优雅部署 GitLab 及防坑指南
linux·docker·gitlab
源图客2 小时前
Linux(CentOS9)服务器部署gitlab-ce-18.11.1-ce.0.el9.x86_64.rpm
linux·服务器·gitlab