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%的文件与文本处理需求,建议结合实际场景反复练习,重点关注日志分析与配置管理类实战案例。

相关推荐
Kina_C5 分钟前
LVS-NAT 负载均衡实验从环境搭建到规则持久化
linux·运维·服务器·负载均衡·lvs
小肝一下18 分钟前
7. 库制作与原理
linux·c语言·操作系统·bash·shell·动静态库
Android洋芋28 分钟前
PrintFriendly网页文章转PDF插件工具及技术分析
运维·服务器·pdf·网页转pdf
Elastic 中国社区官方博客33 分钟前
使用重新设计的 AutoOps 更快地进行 Elasticsearch 问题排查
大数据·运维·前端·人工智能·elasticsearch·搜索引擎·全文检索
RoboWizard1 小时前
金士顿高速闪存盘 单双接口适配多元存储需求
大数据·运维·人工智能·智能手机·云计算
hkj88081 小时前
Ubuntu 20.04 安装 OpenJDK 17
linux·运维·ubuntu
huainingning1 小时前
防火墙重启后ssl登录提示证书过期临时解决方法
linux·服务器·ssl
sulikey1 小时前
服务器安装Docker教程。如何在云服务器安装Docker容器?
运维·服务器·ubuntu·docker·安装教程·云服务器
许彰午1 小时前
17-22-运维与高级主题
运维·网络
万联WANFLOW1 小时前
外贸独立站:服务器放海外国内后台卡,放国内海外客户打不开——这道两头难怎么破?
运维·网络·数据库·经验分享