Linux 通配符与正则表达式(含实战案例+避坑指南)

Linux 通配符与正则表达式全教程(含实战案例+避坑指南)

在Linux运维与开发中,通配符与正则表达式是提升效率的核心工具。前者快速定位文件,后者精准处理文本,二者常被混淆却有着本质区别。本文基于CentOS 7环境,系统梳理语法规则、实战技巧与避坑要点,所有命令均经过验证可直接复现。

一、核心区分:通配符 vs 正则表达式

初学者最易混淆二者,关键差异体现在匹配目标与解析逻辑上,具体对比如下:

维度 通配符(Wildcard) 正则表达式(Regular Expression)
核心用途 匹配文件名/目录名(找文件) 匹配/提取/替换文本内容(处理文件内数据)
解析主体 Shell(Bash)直接解析 文本工具(grep、sed、awk等)解析
匹配单位 以字符为单位,不支持复杂逻辑组合 以模式为单位,支持分组、逻辑运算等复杂规则
转义规则 仅特殊字符需转义(如*? 大量元字符需转义(如^$.等)
典型工具 lsfindcprmmv grep(-E/-P)、sed(-r)、awkvim
实操示例 find /var -name 's*[0-9]*.log'(找日志文件) grep -E '1[3-9][0-9]{9}' test.txt(提手机号)

二、通配符:文件定位的高效利器

通配符由Shell解析,用于快速匹配文件路径,核心价值是简化文件操作。按功能可分为基础通配符、字符类与扩展用法三类。

2.1 通配符完整语法表

类别 符号/语法 作用描述 实操示例(含执行效果)
基础通配符 * 匹配任意长度字符(0个或多个,不匹配隐藏文件) ls /var/log/*.log → 输出:/var/log/messages.log /var/log/secure.log
? 匹配单个任意字符 ls /etc/ifcfg-eth? → 输出:/etc/ifcfg-eth0
[abc] 匹配方括号内任意一个字符 ls /dev/sd[a-d] → 输出:/dev/sda /dev/sdb /dev/sdc /dev/sdd
[!abc]/[^abc] 排除方括号内字符,匹配其他字符 ls /tmp/[!0-9]* → 输出:/tmp/backdoor.sh /tmp/test.txt(排除数字开头文件)
[a-z]/[0-9] 匹配区间内字符(字母/数字) ls file[1-5].txt → 输出:file1.txt file2.txt file3.txt file4.txt file5.txt
Unix字符类 [[:upper:]] 所有大写字母(A-Z) find /opt -name '[[:upper:]]*.sh' → 输出:/opt/BACKDOOR.sh
[[:lower:]] 所有小写字母(a-z) ls [[:lower:]]*.conf → 输出:nginx.conf mysql.conf
[[:digit:]] 所有数字(0-9) ls log_[[:digit:]].txt → 输出:log_1.txt log_2.txt
[[:alpha:]] 所有字母(大小写) ls [[:alpha:]]*.sh → 输出:Test.sh init.sh
路径符号 ~ 当前用户家目录 cd ~ && pwd → 输出:/root(root用户)
- 上一次工作目录 cd /var/log && cd - → 输出:/root
. 当前目录;隐藏文件前缀 ls -a ~ → 输出:.bashrc .ssh .bash_history
.. 上一级目录 cd /var/log/nginx && cd .. && pwd → 输出:/var/log
扩展用法 {,suffix} 批量添加后缀(备份常用) cp /etc/hosts{,.bak}ls /etc/hosts* 输出:/etc/hosts /etc/hosts.bak
{prefix,} 批量添加前缀 mv {a,b,c}.txt doc_{a,b,c}.txt → 生成doc_a.txt等文件
**(需启用globstar) 递归匹配所有子目录文件(Bash 4.0+) shopt -s globstar && ls **/*.txt → 输出所有子目录的.txt文件

注:globstar默认禁用,永久启用需添加shopt -s globstar~/.bashrc

2.2 高频实战练习题(含解析)

测试环境:CentOS 7,root用户,默认系统路径。
1. 找出/var下以s开头、任意小写字母结尾,中间至少1位数字的文件

核心思路 :用*匹配中间任意字符,[0-9]确保数字存在,[a-z]限定结尾。
解法1(基础语法)

bash 复制代码
find /var -type f -name 's*[0-9]*[a-z]'

解法2(标准字符类)

bash 复制代码
find /var -type f -name 's*[[:digit:]]*[[:lower:]]'

执行效果

复制代码
/var/lib/docker/overlay2/xxx/diff/usr/bin/sha1sum
/var/log/sa/sa25
2. 递归查找所有目录中以.conf结尾的文件(两种方案对比)

方案1(globstar快速版)

bash 复制代码
shopt -s globstar && ls **/*.conf

方案2(find通用版,兼容旧系统)

bash 复制代码
find / -type f -name '*.conf' 2>/dev/null  # 重定向错误输出避免权限提示

核心差异:globstar纯Shell解析,比find快2-5倍,但不支持文件属性过滤。

3. 批量创建按日期命名的日志目录(2024年1-3月)

命令

bash 复制代码
mkdir -p /var/log/app/{202401,202402,202403}
# 或用序列扩展(Bash 4.0+)
mkdir -p /var/log/app/2024{01..03}

验证效果

bash 复制代码
ls /var/log/app/
# 输出:202401  202402  202403
4. 备份/var/log/nginx/下7天前的所有日志文件

命令

bash 复制代码
find /var/log/nginx/ -name '*.log' -mtime +7 -exec cp {} {}.old \;

解析-mtime +7筛选7天前修改的文件,{}代表匹配的文件名。

三、正则表达式:文本处理的精准工具

正则表达式用于匹配文本内容,按解析引擎分为基础正则(BRE)和扩展正则(ERE),后者支持更丰富的语法且无需大量转义。

3.1 前置准备:字符集配置

正则易受系统编码影响,建议先统一字符集:

bash 复制代码
export LC_ALL=C  # 强制使用POSIX字符集,避免中文等特殊字符干扰

3.2 正则语法全表(BRE vs ERE)

3.2.1 基础正则(BRE,grep默认支持)
元字符 作用描述 示例(匹配目标) 实操效果(基于test.txt)
^ 匹配行首 ^I(以I开头的行) grep -n '^I' test.txt → 输出:1:I am teacher zack.
$ 匹配行尾 u$(以u结尾的行) grep -n 'u$' test.txt → 输出:8:#my site is https://www.cnblogs.com/pyyu
. 匹配任意单个字符(除换行) f.l(f和l之间1个任意字符) grep -n 'f.l' test.txt → 输出:无匹配
* 匹配前面字符0次或多次 ab*c(ac、abc、abbc等) grep -n 'ab*c' test.txt → 输出:无匹配
[] 匹配方括号内任意字符 [0-9](单个数字) grep -n '[0-9]' test.txt → 输出含数字的行
[^] 排除方括号内字符 [^a-z](非小写字母) grep -n '[^a-z]' test.txt → 输出含非小写字母的行
\ 转义特殊字符 \.$(以.结尾的行) grep -n '\.$' test.txt → 输出:1:I am teacher zack.
.* 匹配任意长度字符(贪婪模式) a.*b(a到b之间所有内容) grep -n 'h.*o' test.txt → 输出:1:I am teacher zack.
3.2.2 扩展正则(ERE,grep -E/sed -r支持)
元字符 作用描述 示例(匹配目标) 实操效果(基于test.txt)
+ 匹配前面字符1次或多次 ab+c(abc、abbc等,不含ac) grep -En 'tt+' test.txt → 输出:3:testtttsss000123566666
? 匹配前面字符0次或1次 colou?r(color、colour) grep -En 'http?' test.txt → 输出:7:$my blog is http://www.zackit.cn
{n} 匹配前面字符恰好n次 [0-9]{11}(11位手机号) grep -En '[0-9]{11}' test.txt -o → 输出:10:15210888008
{n,} 匹配前面字符至少n次 [0-9]{8,}(8位及以上数字) grep -En '[0-9]{8,}' test.txt -o → 输出:9:877348180
{n,m} 匹配前面字符n到m次 [a-z]{2,4}(2-4个连续小写字母) grep -En '[a-z]{2,4}' test.txt → 输出含对应字符的行
` ` 逻辑或(匹配多个模式) `http
() 分组(视为整体处理) `g(la oo)d`(glad或good)
\n 反向引用第n个分组 ([a-z])\1(连续2个相同小写字母) grep -En '([a-z])\1' test.txt → 输出:3:testtttsss000123566666
(?=...) 正向前瞻(后面必须跟指定内容) 1[3-9][0-9]{8}(?=[0-9])(11位手机号) [0-9]{11}效果,用于精准边界匹配

注:Perl正则(grep -P)支持更多高级语法(如\d匹配数字、\b单词边界),但兼容性稍差。

3.3 测试数据与实战练习

测试数据(保存为test.txt):
txt 复制代码
I am teacher zack.
I teach linux,python.
testtttsss000123566666

I like video,games,girls
#I like girls.
$my blog is http://www.zackit.cn
#my site is https://www.cnblogs.com/pyyu
My qq num is 877348180.
my phone num  is 15210888008.
1. 提取所有URL(含http/https)

命令

bash 复制代码
grep -Eo 'http[s]?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' test.txt

解析[a-zA-Z0-9.-]匹配域名主体,[a-zA-Z]{2,}匹配后缀(如cn、com)。
执行效果

复制代码
http://www.zackit.cn
https://www.cnblogs.com
2. 匹配符合yyyy-mm-dd格式的日期(假设文本含日期)

命令

bash 复制代码
grep -Eo '20[0-9]{2}-[01][0-9]-[0-3][0-9]' test.txt

解析:分三段匹配,确保月份1-12、日期1-31的格式合法性。

3. 用sed替换所有旧域名为新域名

需求 :将zackit.cn替换为newdomain.com
命令

bash 复制代码
sed -r 's/zackit\.cn/newdomain\.com/g' test.txt

解析s/旧/新/g是替换语法,.需转义,g表示全局替换。
执行效果

复制代码
$my blog is http://www.newdomain.com
4. 用awk统计文本中数字出现的总行数

命令

bash 复制代码
awk '/[0-9]/{count++} END{print "含数字的行数:"count}' test.txt

解析 :awk按行处理,/[0-9]/匹配含数字的行,END块输出统计结果。
执行效果

复制代码
含数字的行数:3

四、工具选型:grep/sed/awk 适用场景对比

正则的威力需结合工具发挥,三者核心定位不同,搭配使用可解决90%的文本处理需求:

工具 核心定位 优势场景 示例命令(提取手机号)
grep 文本查找/过滤 快速匹配行、提取关键字 grep -Eo '1[3-9][0-9]{9}' test.txt
sed 文本编辑(替换/删除) 批量修改、按模式删除行 sed -r 's/1[3-9][0-9]{9}/[手机号]/g' test.txt
awk 格式化处理(字段级) 数据提取、统计、格式化输出 awk '/1[3-9][0-9]{9}/{print $NF}' test.txt

实战技巧:grep找位置,sed改内容,awk做统计,三者可通过管道组合使用(如grep | sed | awk)。

五、运维高频实战场景

1. 日志分析:提取Nginx 5xx错误请求

需求 :找出nginx_access.log中所有服务器错误的请求IP与URL
命令

bash 复制代码
grep -E ' (500|502|503|504) ' /var/log/nginx/access.log | awk '{print "IP:"$1,"URL:"$7}' | sort | uniq -c

解析(500|502)用空格确保匹配状态码字段,uniq -c统计重复IP。

2. 配置检查:验证sshd_config安全设置

需求 :检查是否允许root直接登录
命令

bash 复制代码
grep -Ev '^#|^$' /etc/ssh/sshd_config | grep -i 'permitrootlogin'

解析 :先排除注释行和空行,-i忽略大小写匹配。

3. 数据统计:TCP连接状态分布

命令

bash 复制代码
ss -tun state all | grep -E 'tcp' | awk '{print $1}' | sort | uniq -c

执行效果

复制代码
  10 ESTABLISHED
   2 LISTEN
   1 TIME_WAIT

4. 批量操作:修改所有.conf文件权限

命令

bash 复制代码
shopt -s globstar && chmod 644 **/*.conf

解析:globstar递归匹配所有子目录的.conf文件,644确保读写权限合规。

六、避坑指南与学习技巧

1. 常见误区

  • 通配符与正则的*混淆 :通配符*匹配任意字符,正则*匹配前面字符0次或多次(如a*匹配空、a、aa等)。

  • 未转义特殊字符 :正则中的.$()需转义(BRE),通配符中的*?在引号内无需转义。

  • globstar兼容性问题 :CentOS 7默认Bash 4.2支持globstar,但需手动启用,脚本中建议添加检查:

    bash 复制代码
    if ! shopt -q globstar; then echo "globstar未启用,请升级Bash"; fi

2. 效率提升技巧

  • 在线调试工具:用Regex101(https://regex101.com/) 实时验证正则表达式,支持Linux模式。
  • 字符类优先用标准写法[[:digit:]][0-9]兼容性更好(支持非ASCII数字)。
  • 避免过度使用正则 :简单文件匹配用通配符,比find+正则更快(如ls *.txt优于find . -regex '.*\.txt')。

七、总结

  1. 通配符 :聚焦"文件定位",是Shell的内置功能,核心是*?[]{}的组合使用。
  2. 正则表达式 :聚焦"文本处理",依赖外部工具解析,ERE(grep -E)是日常运维的最优选择。
  3. 实战核心:先明确需求是"找文件"还是"处理文本",再选择工具,复杂场景通过管道组合三者优势。

掌握本文内容可覆盖Linux日常运维中90%的文件与文本处理需求,建议结合实际场景反复练习,重点关注日志分析与配置管理类实战案例。

相关推荐
带土13 小时前
18 .shell编程-正则表达式
linux·正则表达式
勤源科技3 小时前
运维知识图谱的构建与应用
运维·人工智能·知识图谱
jiyuzzz3 小时前
Docker部署WordPress及相关配置
运维·docker·容器
爱吃甜品的糯米团子3 小时前
Linux 学习笔记之进程管理、网络基础与常用软件安装
linux·网络·学习
Micro麦可乐3 小时前
Centos Stream 9 中Docker安装出现 download.docker.com:443 的问题解决
linux·docker·centos·podman
poemyang4 小时前
你的程序为何卡顿?从LINUX I/O三大模式寻找答案
linux·rpc
---学无止境---4 小时前
Linux中早期控制台初始化和注册的实现
linux
撬动未来的支点4 小时前
DMABUF 核心概念:Linux 的“共享白板”机制
linux
今麦郎xdu_5 小时前
【Linux系统】命令行参数和环境变量
linux·服务器·c语言·c++