字数 3111,阅读大约需 16 分钟
接触Linux一段时间后,你难免会遇到这些场景:从海量系统日志中提取错误信息、快速找出含特定关键词的配置文件、批量筛选符合规则的文本内容……手动处理不仅效率低下,还容易出错,而**正则表达式(Regular Expression,RE)**就是解决这些问题的高效工具。

简单来说,正则表达式不是某个具体工具,而是一套字符串处理的标准规则——通过特殊字符的组合,实现对字符串的搜索、替换、删除等操作。只要Linux工具支持这套规则(比如grep、vim、egrep等),就能借助它完成复杂的字符串处理,这也是它成为系统管理员必备技能的核心原因。
很多人会把正则表达式和Shell通配符混淆,这里必须划清界限:
ls *.txt中的*),仅用于匹配文件名等简单场景;正则表达式的应用场景十分广泛:邮件服务器的垃圾邮件过滤、系统日志分析、服务器软件的规则配置等,都离不开它。掌握它,能让你的Linux文本处理工作效率翻倍。
开始学习正则语法前,必须先解决两个关键问题:语系对匹配结果的影响,以及核心工具grep的使用,否则后续实操很容易出现“结果与预期不符”的情况。
Linux的语系设置会直接改变文本编码顺序,进而影响正则匹配结果。比如英文大小写的编码顺序:
LANG=C时,编码顺序是0-9→A-Z→a-z,[A-Z]能精准匹配所有大写字母;LANG=zh_CN.UTF-8时,编码顺序混乱,[A-Z]可能会匹配到部分小写字母。因此,实操正则表达式时,建议先执行export LANG=C切换到C语系,确保匹配结果的准确性。
为了彻底摆脱语系影响,Linux提供了预定义字符类,比直接写a-z、A-Z更可靠,常用类别一定要记牢:
[[:digit:]]比[0-9]更稳妥,完全不受语系干扰。 |
grep是Linux中最常用的文本搜索工具,完美支持基础正则表达式,核心功能是按行匹配字符串,输出匹配到的整行内容。先掌握它的进阶选项,后续正则练习会更顺畅:
grep [-n] [-v] [-i] [-A n] [-B n] [--color=auto] '匹配规则' 文件名实用小技巧:每次输入--color=auto太麻烦,可在~/.bashrc中添加别名,让颜色自动生效:
alias grep='grep --color=auto'
source ~/.bashrc # 立即生效实操示例:从系统核心日志中查找网卡(eth)相关信息,显示行号并标色:
dmesg | grep -n 'eth'若想查看匹配行的前2行和后3行,只需补充参数:
dmesg | grep -n -A3 -B2 'eth'基础正则表达式是所有用法的核心,掌握以下特殊字符,就能解决80%的日常文本处理需求。为了方便练习,我们先创建测试文件regular_express.txt(内容如下),后续所有示例均基于此文件:
"Open Source" is a good mechanism to develop programs.
apple is my favorite food.
Football game is not use feet only.
this dress doesn't fit me.
However, this dress is about $ 3183 dollars.
GNU is free air not free beer.
Her hair is very beauty.
I can't finish the test.
Oh! The soup taste good.
motorcycle is cheap than car.
This window is clear.
the symbol '*' is represented as start.
Oh! My god!
The gd software is a library for drafting programs.
You are the best is mean you are the no. 1.
The world <Happy> is the same with "glad".
I like dog.
google is the best tools for search keyword.
goooooogle yes!
go! go! Let's go.
# I am VBird
(最后一行是空白行)直接输入要匹配的字符串,即可实现精准搜索,结合grep选项可灵活拓展:
the的行,显示行号:grep -n 'the' regular_express.txtthe的行:grep -vn 'the' regular_express.txtthe/The:grep -in 'the' regular_express.txt[]代表匹配其中任意一个字符,适用于有相似性的字符串匹配。比如同时匹配test和taste,两者核心结构是t?st,用[ae]匹配中间字符即可:
grep -n 't[ae]st' regular_express.txt # 仅匹配test或taste[]中加^表示反向选择,即“不匹配其中任意字符”。比如匹配oo,但oo前面不能是g:
grep -n '[^g]oo' regular_express.txt若要匹配连续字符范围,可在[]中用-,比如:
oo前面不是小写字母的行:grep -n '[^a-z]oo' regular_express.txtgrep -n '[0-9]' regular_express.txtgrep -n '[^[:lower:]]oo' regular_express.txt^和$是定位符,分别表示行首和行尾,搭配使用可实现精准行匹配,是日志分析的常用技巧:
grep -n '^the' regular_express.txt(仅第12行匹配)grep -n '^[a-z]' regular_express.txtgrep -n '^[^a-zA-Z]' regular_express.txt(第1行和第21行)grep -n '\.$' regular_express.txt(小数点是特殊字符,需用\转义)grep -n '^$' regular_express.txt(仅最后一行匹配)实用场景:查看配置文件时,过滤注释行(#开头)和空白行,只显示有效配置:
grep -v '^$' /etc/syslog.conf | grep -v '^#'.:代表任意一个字符(必须有一个,不能为空);*:代表重复前一个字符0次或无限次,需和其他字符搭配使用。示例1:匹配g??d形式的字符串(g和d之间有2个任意字符):
grep -n 'g..d' regular_express.txt # 匹配good、glad等示例2:匹配至少含2个o的字符串,用oo*(第一个o必选,第二个o可重复):
grep -n 'oo*' regular_express.txt示例3:匹配任意字符组合,用.*(.是任意字符,*是重复,合起来表示“0个或多个任意字符”)。比如匹配以g开头、g结尾的字符串:
grep -n 'g.*g' regular_express.txt*只能表示0次或无限次,若要限定具体重复范围,需用{},语法为:
{n}:重复前一个字符n次;{n,m}:重复前一个字符n到m次;{n,}:重复前一个字符至少n次。注意:{}在Shell中有特殊含义,需用\转义(即\{n\}、\{n,m\})。
o的字符串:grep -n 'o\{2\}' regular_express.txto再接g的字符串:grep -n 'go\{2,5\}g' regular_express.txto再接g的字符串:grep -n 'go\{2,\}g' regular_express.txt基础正则能解决大部分问题,但遇到多条件“或”匹配、精准重复群组时,写法繁琐,而延伸正则表达式通过新增特殊字符,让复杂匹配更简洁。
延伸正则需用egrep或grep -E执行(egrep是grep -E的别名,更易记),核心特殊字符如下:
和*的区别:*可重复0次,+必须至少1次。比如匹配god、good、goood等(g和d之间至少1个o):
egrep -n 'go+d' regular_express.txt适用于匹配“可有可无”的字符,比如匹配gd或god(g和d之间0个或1个o):
egrep -n 'go?d' regular_express.txt这是延伸正则的实用功能,可同时匹配多个字符串,替代多次grep操作。比如同时匹配gd、good、dog:
egrep -n 'gd|good|dog' regular_express.txt实用场景:一次性过滤注释行和空白行,替代两次反向匹配:
egrep -v '^$|^#' regular_express.txt()用于将多个字符归为一个群组,结合|可实现群组间的或匹配。比如同时匹配glad和good,两者共同部分是g?d,将中间的la和oo分组:
egrep -n 'g(la|oo)d' regular_express.txt表示整个群组重复至少1次,适用于匹配连续的群组字符串。比如匹配AxyzxyzC(A开头、C结尾,中间至少1个xyz):
echo 'AxyzxyzxyzC' | egrep 'A(xyz)+C'掌握正则核心语法后,再学习几个文件处理实用技巧:格式化输出printf、文件比对diff/cmp、补丁制作patch,让文本处理更完整。
printf是比echo更强大的输出工具,可自定义格式,常用于结构化数据展示,语法:
printf '格式化规则' 实际内容常用格式化规则:
%ns:n个字符的字符串;%ni:n个字符的整数;%n.mf:总长度n,保留m位小数的浮点数;\t:Tab键,\n:换行。示例:创建printf.txt存储成绩数据,用printf格式化输出:
# printf.txt内容
Name Chinese English Math Average
DmTsai 80 60 92 77.33
VBird 75 55 80 70.00
Ken 60 90 70 73.33
# 格式化输出,列对齐
printf '%10s %5i %5i %5i %8.2f \n' $(cat printf.txt | grep -v Name)# 比对passwd.old和passwd.new的差异
diff passwd.old passwd.new还能比对整个目录的差异:
diff /etc/rc3.d/ /etc/rc5.d/# 比对两个文件的第一个差异:cmp passwd.old passwd.new结合diff制作补丁文件,可将旧版本文件快速升级为新版本,避免重复修改:
diff -Naur生成标准化补丁(.patch):diff -Naur passwd.old passwd.new > passwd.patchpatch -p0 < passwd.patchpatch -R -p0 < passwd.patch正则表达式是Linux中最强大的文本处理工具之一,看似有入门门槛,但只要掌握基础语法和实用工具,就能让繁琐的文本处理工作变得高效简洁。从今天开始,把正则融入日常操作,你会发现处理日志、筛选文本、比对文件都能事半功倍!