三剑客-grep正则

5891 字
29 分钟
三剑客-grep正则

三剑客-grep正则#

[TOC]


特殊符号#

引号系列:#

引号类型含义说明
单引号 '...'==所见即所得==,内容原封不动输出,不解析任何特殊字符
双引号 "..."会解析内部的 ()/反引号==命令替换==)和 ()** / `反引号`(==命令替换==)和 ** {}(变量操作),也支持 \ 转义;
不解析花括号展开(如 {1..10}),它们会被当作普通文本输出
不加引号在双引号的基础上,额外支持花括号展开(如 {a..e})和通配符匹配(如 *.log
但因空格、换行等特殊字符会导致单词分裂或意外展开,需谨慎
反引号优先执行反引号里面的命令,功能完全等价于 ()<br>但因不支持嵌套且可读性差强烈推荐使用()** <br>*但因不支持嵌套且可读性差*,**强烈推荐使用 () 替代
Tip

常见的通配符: *(任意个字符) ?(单个字符) { }(花括号序列输出)

Terminal window
1)单引号:完全原样输出,无任何解析
echo 'kpyun $(date +%Y) ${USER} {a..b}'
# ✅ 输出: kpyun $(date +%Y) ${USER} {a..b}
2)双引号:解析 $() 和 ${},但不解析花括号
echo "kpyun $(date +%Y) ${USER} {a..b}"
# ✅ 输出: kpyun 2026 root {a..b}
3)不加引号:全部解析,包含花括号展开与通配符匹配
echo kpyun $(date +%Y) ${USER} {a..b}
# ✅ 输出: kpyun 2026 root a b
[root@shell ~]# touch {1..3}.log
[root@shell ~]# ls "*.log" ❌ 不支持
ls: cannot access No such file or directory
[root@shell ~]# find ./ -name "*.log" ✅ 支持
./1.log
./2.log
./3.log
[root@shell ~]# ls *.log
1.log 2.log 3.log
4)反引号:等价于 $(),但不推荐
echo `date +%Y`
# ✅ 输出: 2026
# ⚠️ 推荐写法: echo $(date +%Y)

通配符#

符号名称含义与匹配规则典型用法示例
*星号匹配任意长度(包括零个)的任意字符ls *.txtrm *log*
{}花括号输出序列,用于生成一组特定顺序的字符串(可包含数字或字母)touch file{1..5}.txt
cp a.txt{,.bak} (相当于 cp a.txt a.txt.bak)
[]方括号字符集合匹配。匹配括号内任意一个列出的字符ls [abc]* (列出以 a、b 或 c 开头的文件)
rm file[0-9].log (删除 file0.log 到 file9.log)
?问号匹配任意一个单一字符ls file?.txt (匹配 file1.txt, fileA.txt,但不匹配 file10.txt)

📌 通配符:主要用于批量查找文件(模糊匹配文件名)

*星号#

Terminal window
find /home -name "*.txt" -type f
# 在/home目录下找后缀为.txt的文件

{}花括号#

它还可以创建各种序列,详细笔记请看 📚必会命令②

Terminal window
1)不连续输出 (逗号分割)
jiuzhao@Ubuntu test$ echo a{b,c}
ab ac
2)前后缀拼接 (只扩展后半部分)
jiuzhao@Ubuntu test$ echo oldboy{,bak}
oldboy oldboybak
3)利用花括号生成备份文件 (cp + 花括号)
jiuzhao@Ubuntu test$ echo "hhh" > hh.txt
jiuzhao@Ubuntu test$ ls
hh.txt
jiuzhao@Ubuntu test$ cp hh.txt{,.bak}
# 核心命令:利用花括号扩展,自动变成 cp hh.txt hh.txt.bak
jiuzhao@Ubuntu test$ ls
hh.txt hh.txt.bak
# 查看结果,你会看到生成了 hh.txt.bak

[]中括号#

📌 支持序列

查看文件名支持数字序列

很少用到

Terminal window
[root@oldboyedu ~]# ll [0-9].txt
-rw-r--r-- 1 root root 0 Nov 7 11:18 0.txt
-rw-r--r-- 1 root root 28 Nov 7 11:09 1.txt
# 匹配 0.txt 到 9.txt 中的文件

支持字母序列

Terminal window
[root@oldboyedu ~]# touch u.txt
[root@oldboyedu ~]# ll [a-z].txt
-rw-r--r-- 1 root root 0 Nov 7 11:23 u.txt
# 这个ll 相当于匹配 ll a.txt 或者 ll b.txt 或者 ll c.txt ... 或者 ll z.txt
'逐个匹配,有一个就显示一个'

基础正则表达式#

  • 本质:正则表达式本身是一些符号的集合(⚠️注意:必须使用英文半角符号,如果用了中文全角符号如 ‘’ 会导致命令报错)。
  • 作用:它是一种高级的字符过滤工具,专门用于对文件内容(如日志数据)进行模式匹配和提取

(1)正则表达式就是为了处理大量的 文字|文本|字符串 而定义的一套规则和方法

(2)通过定义的这些特殊符号的辅助,系统管理员就可以快速过滤替换输出需要的字符串

(3)过滤时,推荐使用单引号进行过滤

对比维度**正则表达式 **通配符
匹配对象匹配文件内容(即文件里的文字、符号)匹配文件名(或命令参数)
支持命令Linux 三剑客grepsedawk)及编程语言Linux 绝大多数基础命令(如 lscprm
Terminal window
jiuzhao@Ubuntu test$ alias | grep grep
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
正则类型核心符号功能简述
基础正则 (BRE)^锚定行首(例如 ^root 匹配以 root 开头的行)
$锚定行尾(例如 bash$ 匹配以 bash 结尾的行)
.匹配任意单个字符
*匹配前一个字符出现 0 次或多次
.*匹配任意长度的任意字符(即“贪婪”匹配所有内容)
[]匹配括号内任意一个列出的字符(如 [0-9] 匹配数字)
[^]匹配不在括号内列出的任意一个字符(取反)
扩展正则 (ERE)``
+匹配前一个字符出现 1 次或多次
()将括号内的内容作为整体进行分组匹配
{}匹配前一个字符出现的精确次数(如 {3,5} 表示 3 到 5 次)
?匹配前一个字符出现 0 次或 1 次
Tip

💡 进阶提示:在 Linux 中,使用 grep 命令时,如果想要使用扩展正则(如 +, |, ()),通常需要加上 -E 参数,或者使用 egrep 命令

✅️ 提前准备一段素材

Terminal window
cat >./re.txt<<EOF
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
my qq is 49000448
not 4900000448.
my god ,i am not oldbey,but OLDBOY!
aaaa,
not 572891888887.
^^^^^^^^66$$$$$$$^^^$$
lizhenyalizhenyalizhenya
$taaaaaaaaaaaaaaaaaa
EOF

1) ^ 以…开头的行#

📌 肩号(6)

以I开头的行

Terminal window
jiuzhao@Ubuntu test$ grep '^I' re.txt
# 匹配以 I 开头的行
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!

2) $ 以…结尾的行#

📌 doll符(4) —> ⚠️ 是$而不是&

Terminal window
jiuzhao@Ubuntu test$ grep '8$' re.txt
# 匹配以数字8结尾的行
my qq is 49000448

📌 cat -A 显示出文件中的特殊隐藏符号,每一行以$结尾

✅️ 实践:如何找到以m结尾的行

Terminal window
grep 'm$' re.txt
# 匹配以 m 结尾的行
'最常见的就是有隐藏的符号,导致过滤不出来'
Note

在 Linux 文本文件中,行末往往带有肉眼看不见的“特殊符号”(如空格、制表符)'m$' 的意思是“m 必须作为这一行绝对的最后一位

如果一行实际内容是 blog.51cto.com(注意后面有两个空格),那么它并不是m 结尾,而是以 空格 结尾,所以 grep 'm$' 匹配不到

💡 终极排查工具:cat -A

  • 用法cat -A 文件名
  • 作用:它能让文件中的隐藏字符现出原形
    • 行尾的真实换行符会显示为 $
    • 行尾的空格会显示为 空格(或者在某些系统中显示为 ·
Terminal window
iuzhao@Ubuntu test$ cat -A re.txt
I am oldboy teacher!$
I teach linux.$
$
I like badminton ball M-oM-<M-^Lbilliard ball and chinese chess!$
my blog is http://oldboy.blog.51cto.com $
our size is http://blog.oldboyedu.com $
Tip

💡 核心启示:写正则时,尤其是用到 $(行尾)和 ^(行首)时,肉眼看到的“结尾”并非真正的结尾,遇到匹配不上时,cat -A 是必杀技


同样是m,^m$ 这个又是什么意思呢?

  • 字面上看,以m开头,又以m结尾的行
  • 也就是这一行只有一个字母,就是m
Terminal window
grep '^m$' re.txt
# 匹配只有单独一个字母 m 的行

3) ^$ 空行#

📌 这行中没有任何字符

过滤出文件中的空行并显示行号

Terminal window
grep -n '^$' re.txt
# -n 显示行号,过滤空行
jiuzhao@Ubuntu test$ grep -n '^$' re.txt
3:
7:
10:
12:
16:
18:

⚠️ 过滤时,推荐使用单引号进行过滤

grep -v 选项#

📌 对取到的内容的行进行取反

它是对行取反

✅️ 案例:取出文件中除了空行以外的行

Terminal window
grep -v '^$' re.txt
# -v 取反,排除空行
# 排除空行,显示所有有内容的行
jiuzhao@Ubuntu test$ grep -v '^$' re.txt
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
my qq is 49000448
not 4900000448.
my god ,i am not oldbey,but OLDBOY!
aaaa,
not 572891888887.
^^^^^^^^66218532185321853$^^^21853
lizhenyalizhenyalizhenya
Note

[^abc] 他也是取反——取不包含这些字符的行,这些行仍然可以包含a,b,c

⚠️ 注意区分: [^abc] 是对字符取反, grep -v 是对取反

grep -n(显示行号)#

📌 显示过滤内容的行号

上面这个过滤出空行,总感觉很傻

Terminal window
grep -nv '^$' re.txt
# -n 显示行号
# -v 排除
# 因为我们一般看配置文件都是不看空行的

📌 配置文件的查看

上面说的是不看空行,但其实,有一些备注释的行(#开头),我们也是不看的

✅️ 案例:排除文件中以#开头的行

Terminal window
grep -v '^#' /etc/ssh/sshd_config
# 排除以 # 开头的注释行

✅️ 案例:只显示文件中生效的行、排除了注释行和空行

Terminal window
grep -v '^$' /etc/ssh/sshd_config | grep -nv '^#'
# 第一次用 -v 过滤空行(不加 -n,否则数字打头无法过滤#开头)
# 第二次用 -nv 排除#注释行并显示行号
'因为我们后面要过滤到以#号开头的行,所以我们第一次过滤只用 -v 而不是 -nv'

grep -c (统计行数)#

📌 统计过滤到内容的行数

但其实不经常用, 我们通常用wc -l来统计行数

Terminal window
grep -c 'oldboy' re.txt
# 统计包含 oldboy 的行数
'一般用 wc -l 更多' 能实现同样的效果
jiuzhao@Ubuntu test$ grep -n 'oldboy' re.txt
1:I am oldboy teacher!
5:my blog is http://oldboy.blog.51cto.com
6:our size is http://blog.oldboyedu.com
jiuzhao@Ubuntu test$ grep -c 'oldboy' re.txt
3
jiuzhao@Ubuntu test$ grep -n 'oldboy' re.txt | wc -l
3

grep -w (精确匹配)#

Terminal window
grep -w 'oldboy' re.txt
# -w 精确匹配整个单词,不匹配 oldboyxxx 这种

边界符#

📌 用于匹配单词的开始或结束位置

确保匹配的是完整单词,而不是某个单词的一部分

✅️ 常见的边界符(在 grep 中)

和 grep -w的功能有一点类似

  • \b 开头结尾都匹配
  • \< 匹配单词开头
  • \> 匹配单词结尾
Terminal window
grep '\<user\>' file.txt
# 精确匹配单词 user
'也可以这样写 \buser\b'
[root@oldboy home]# echo 'username' | grep '\busername\b'
username
# \b 边界符匹配
[root@oldboy home]# echo 'username' | grep '\<username\>'
username
# \< \> 等价写法
[root@oldboy home]# echo 'username' | grep -w 'username'
username
# -w 也是精确匹配,效果一样
jiuzhao@Ubuntu test$ echo 'username' | grep -w 'user' | wc -l
0 '并没有匹配到'

-A -B -C#

  • -A num 后接数字,显示匹配行后的num行
  • -B num 显示匹配行前的num行
  • -C num 显示匹配行前后的num行
Terminal window
grep -A 2 'qq' re.txt
# 显示匹配行及其后2行
jiuzhao@Ubuntu test$ grep -A2 'qq' re.txt
my qq is 49000448
not 4900000448.

grep -r#

📌 递归过滤文件内容 重要

Terminal window
# 我们/code/1.html 页面被污染,
# 还有/code/oldboy/index.html 这个页面也被污染了
grep 'www.cjj.com' /code
# 它默认只过滤 /code/ 这个目录下的文件,不递归目录
# 方式一: 递归过滤
grep -r 'www.cjj.com' ./code
# -r 才能递归到 /code/oldboy/index.html 下的页面
# 方式二: find + xargs
find ./code -type f | xargs grep 'www.cjj.com'
# 先用find找所有的文件,然后再进行过滤

4) . 任意一个字符#

📌 表示任意单个字符、1次匹配1个字符

oldb任意一个字符y

Terminal window
grep 'oldb.y' re.txt
# . 匹配任意单个字符

了解: .过滤的时候会排除空行, 点不会匹配空行

grep -o 选项#

📌 展示grep命令的执行过程

Terminal window
grep -o 'oldb.y' re.txt
# -o 只输出匹配的部分,显示执行过程

. (点) 匹配任意一个字符,它是一行一行的匹配的

grep -i 选项(忽略大小写)#

Terminal window
grep -i 'oldboy' re.txt
# -i 忽略大小写,匹配 Oldboy OLDBOY 等

5) \ 撬棍#

✅️ 还可以作为’转义行’

Terminal window
# 一行塞不下了,换一行进行书写!
[root@localhost home]# ll \
> -rnt
# 时间倒序排,最先修改的排在下面!
# 继续在第二行写了!
total 8
-rw-r--r--. 1 0 0 0 Mar 4 09:45 a.txt
drwx------. 2 1000 1000 4096 Mar 4 09:46 test
-rw-r--r--. 1 0 0 113 Mar 4 12:33 all.tar.gz

📌 基础正则中: 是转义字符 脱掉马甲打回原形,去掉特殊符号的含义

找出文件中以.(点)结尾的行

. 点 在基础正则中是匹配任意个字符 一个撬棍打回原形

Terminal window
grep '\.$' re.txt
# \ 转义 . 使其变回普通字符(点),匹配以 . 结尾的行

Important

基础正则: 转义字符 脱掉马甲打回原形,去掉特殊符号的含义

未来在扩展正则中\撬棍, 唤醒前世记忆从而含有特殊含义了

一会打回原形,一会又有了特殊含义???

上个命令是grep, 那如果我们如果用egrep呢?

后面我们命令用的最多的就是egrep进行正则过滤; 所以我们的撬棍只需要记住: “打回原形”

6) * (表示重复或连续出现)#

📌 前一个字符连续出现0次或0次以上

这个符号刚开始学习正则的时候不常用,刚刚开始的时候掌握什么叫连续出现即可

Terminal window
# 示例: 理解"连续出现"的含义
1 # 数字1出现1次
111 # 数字1出现3次
123 # 数字出现3次
oldboy # 字母出现6次
oldboy996 # 连续出现的数字和小写字母
Lidao996 # 连续出现的数字和大小写字母

关于出现0次: 这个符号没有的意义

⚠️ 如果没有则输出整个文件内容

Terminal window
grep '0*' re.txt
# * 是前一个字符出现0次或0次以上
# 0次意味着不出现也会被匹配,因此输出所有行

7) . 所有(或者是)(连续出现)*#

  • . 任意一个字符
  • * 前一个字符连续出现0次或0次以上
  • .* 表示所有

以任意内容开头直到匹配到am字符的行

Terminal window
grep '^.*am' re.txt
# 以任意内容开头,直到匹配到 am 字符的行

任意内容开头,直到匹配到am字符的行

📌 你贪婪吗?

正则表示连续出现的时候,表示所有的时候,体现出贪婪性(尽可能多的匹配)(不分好坏)

匹配开头一直到字母o的内容

Terminal window
grep '^.*o' re.txt
# 匹配到最后一个字母o,而不是只匹配一个字母o
'这就是贪婪匹配!'

当然你也可以避免匹配到这种贪婪性,就是多写个字母,ol而不是一个字母o(加上限制条件)

8) []#

📌 [abc] 表示匹配任意1个字符,a或b或c,中括号相当于一个字符

⚠️ 找出文件包含a的行 或者 b的行 或者 c的行 而不是abc的行

温馨提示: [ ]中会自动去掉符号的特殊含义

Terminal window
# 括号家族速览
() # 小括号
[] # 中括号
{} # 大括号 花括号

✅️ 案例:找出包含abc的行

Terminal window
[root@oldboyedu ~]# cat 1.txt
abcde
bacioeirt
uuuuuuuuuuu
[root@oldboyedu ~]# grep 'abc' 1.txt
abcde
# 精确匹配 abc 三个连续字母

✅️ 案例:找出行中包含a或b或c的行

Terminal window
[root@oldboyedu ~]# grep '[abc]' 1.txt
abcde
bacioeirt
# [abc] 匹配包含 a 或 b 或 c 的行
[root@oldboyedu ~]# grep -o '[abc]' 1.txt
a
b
c
b
a
c
# -o 显示匹配过程,逐个字符匹配

只要有abc其中的一个都能够匹配到

-o 显示grep的执行过程

如果想匹配到其中任意的两个连续字符

Terminal window
grep '[abc][abc]' 1.txt
# 一个中括号表示一个字符,两个中括号匹配两个连续的 a/b/c

⚠️ grep ‘[10]’ re.txt — 它是匹配数字10嘛? 显然不是,是匹配数字,只要有数字1或者数字0都会匹配到

✅️ grep ‘10’ re.txt — 这个才是匹配数字10

Terminal window
# 匹配数字
grep '[0-9]' re.txt
# 匹配小写字母
grep '[a-z]' re.txt
# 匹配大写字母
grep '[A-Z]' re.txt
# 匹配大小写字母
grep '[a-zA-Z]' re.txt
# ⚠️ [a-z,A-Z] 这个写法是错误的!
# 中间不能加逗号, 如果加了则逗号也会匹配上去
# 同理也不能加空格
# [a-Z] 如果这个用不了使用上面完整形式

匹配大小写字母+数字

Terminal window
grep '[a-zA-Z0-9]' re.txt
grep '[a-Z0-9]' re.txt
grep '[0-Z]' re.txt
# 最后一个简单明了

匹配出以字母m或n开头的行

Terminal window
grep '^[mn]' re.txt
# 匹配以 m 或 n 开头的行

匹配出以 .空格! 结尾的行

Terminal window
grep '[. !]$' re.txt
# [ ] 中会自动去掉符号的特殊含义

Terminal window
# 我们再来试试普通的过滤 ' '
grep ' $' re.txt
# 匹配以空格结尾的行

9) [^] 排除#

📌 只有把^号放在第一个位置才是排除,其他位置都不是

[^abc] 表示匹配任意1个字符,排除abc

Note

建议掌握正则一段时间后再来理解与使用

Terminal window
grep '[^abc]' re.txt
# 匹配包含 a,b,c 以外的任意字符的行
# ⚠️ 只是对字符取反,并不是对行取反!

第二个^失去特殊含义 就是一个普通字符

Terminal window
grep '[a^bc]' re.txt
# ^ 不在第一个位置,就只是普通字符

Terminal window
grep '[abc]' re.txt
# 匹配含有a或者b或者c的行
grep '[^abc]' re.txt
# 匹配不含有a或b或c... 是这样吗???
# ⚠️ 不对! 他只是对字符取反,并不是对行取反!
# 对行取反用 grep -v 选项
'只是不匹配a或b或c中的任意一个字符了'
'但是如果这一行含有a或者b或者c之外的字符,就会被匹配出来'
# 再来个例子加强一下印象,不要搞错
egrep '[^$]' re.txt
# [^$] 不等于 ^$!不要混淆

小结基础正则#


03.扩展正则表达式#

Terminal window
egrep # 支持扩展正则
grep -E # grep不支持扩展正则,加 -E 启用
sed -r # sed 使用 sed -r 支持扩展正则
awk # awk 默认支持扩展正则

1) +#

📌 前一个字符连续出现1次或1次以上

*号(基础正则)是0次或0次以上

✅️ + 大部分配合着[ ]一起使用

取出连续出现的0

Terminal window
grep '0*' re.txt
# * 匹配0次或0次以上
grep -E '0+' re.txt
# + 匹配1次或1次以上
egrep '0+' re.txt
# 等价于上一条
'以上三条命令等价,也是简单介绍扩展正则如何使用'

我们来看一下有’+‘号和没有’+‘的区别

Terminal window
egrep '0' re.txt
# 只要有一个0就匹配
egrep '0+' re.txt
# 至少有一个0才匹配,连续0越多越匹配

egrep -v 选项#

📌 排除符合条件的行

Terminal window
egrep -v '0+' re.txt
# -v 排除包含连续0的行

取出连续出现的数字

Terminal window
egrep '[0-9]+' re.txt
# 匹配连续出现的数字

取出连续出现的字母(单词)

Terminal window
egrep '[a-zA-Z]+' re.txt
# 匹配连续出现的字母(单词)

因为+是匹配前一个字符连续出现1次或1次以上

2) | 或者#

文件中包含oldboy或linux的行

📌 最常用的就是过滤一些整体的内容

[ ]中括号就是过滤数字啊,大小写字母啥的(单个的单个的),只要包含就会呈现出来

Terminal window
egrep 'oldboy|linux' re.txt
# | 表示或,匹配 oldboy 或 linux

在某个目录下/etc/services,过滤出ssh或http或smtp服务

Terminal window
egrep 'ssh|http|smtp' /etc/services
# 同时过滤多个服务

✅️ 案例:找出空行或者以#开头的行

Terminal window
[root@oldboyedu ~]# egrep '^$|^#' /etc/selinux/config
# 匹配空行或注释行

✅️ 排除/etc/ssh/sshd_config中的空行或注释,输出的时候显示行号

Terminal window
# 方法一: grep 管道(需要两次过滤)
grep -v '^$' /etc/ssh/sshd_config | grep -nv '^#'
# 方法二: egrep 一行搞定
egrep -nv '^$|^#' /etc/ssh/sshd_config
# 相比grep, 扩展正则更方便一点

**另一种方法: **直接过滤字母开头的行

Terminal window
grep '^[a-Z]' /etc/ssh/sshd_config
# 匹配以字母开头的行,自动排除空行和注释行

3) () 表示一个整体#

📌 用于后向引用(反向引用sed)

寻找oldboy或者是oldbey

Terminal window
egrep 'oldb(o|e)y' re.txt
# () 把 o|e 作为一个整体
'你得小括号括起来'

4) {} a{n,m}#

📌 使用频率不高,可以通过{}精准控制出现的次数

前一个字符连续出现至少n次,最多m次

它可以表示一个范围,a{n}匹配固定的次数

Terminal window
egrep '0{3}' re.txt
# 0连续出现3次

想生成一行一行的随机IP地址?

Terminal window
echo {1..255}.{1..255}.{1..255}.{1..255}
# 生成大量IP地址组合,但写在一行
'遗憾的是它写在了一行,怎么把它变为一行一行的分开写?'

✅️ 改为一行一行分开写

Terminal window
echo {1..255}.{1..255}.{1..255}.{1..255} | xargs -n1
# 用 xargs -n1 每行输出一个
# 或者用 tr 替换空格为换行
echo {1..255}.{1..255}.{1..255}.{1..255} | tr ' ' '\n'

{,3} 最多3次,最少0次,也就是一次也不出现

Terminal window
egrep '0{,3}' re.txt
# 0出现0次到3次

⚠️ 仔细看前面'{3}' 连续出现3次,有一个4900000448(五个零)依旧被过滤了出来,贪心算法

'0{3}' 这样就只会过滤出0,如果刚好有六个或者更多连续的0,也都会被过滤出来,因为你的这个0前后左右并没有什么约束条件

✅️ 当你加上前后的约束条件,答案就会变得截然不同

Terminal window
egrep '490{3}4' re.txt
# 当你加上前后的约束条件,答案就会变得截然不同
'也就是你想阻止这个贪心算法,你就要写更多的约束条件了'

🌰 案例: 匹配身份证号

Terminal window
# 分析规律:
# 18位 数字或X
# X在最后一位
# 身份证: 18位 17位是数字 最后1位数字或X

✅️ 数据集

Terminal window
# 数据集
# 谈媚轩 230189199012251659
# 庾菲刚 23018199012015108
# 桑春 23018215507074953
# 范惠融 230182197510240695
# 霍莎 23018219590413055X
# 单燕可 230182197007233320
# 雷聪 23018215709180586
# 郑芬澜 23018199402088233
# 阙宁茜 230182198305100379
# 赵璧桂 23018195312204747
# 史勤 23018218107207651
# 项珠 230182195305221943
# 季艳盛 230182195604045725
# 吕进 230182196412284021
# 翟竹静 230182196102271858
# 翟竹静 23018219610227
# 翟竹静 2301821922
# 翟竹静 230181922
Terminal window
egrep '[0-9]{17}(X|[0-9])$' id.txt
# 17位数字 + 最后1位数字或X

Terminal window
egrep '[0-9]{17}[0-9X]' id.txt
# 还可以更加的简便一点

稍微复杂严谨一点的匹配身份证的正则这些就是开发的事情了(网图)

5) ? 0次或1次#

📌 前一个字符 出现0次或1次

Terminal window
egrep 'oldb?oy' re.txt
# ? 前一个字符(b)出现0次或1次

6) 扩展正则小结#

⚠️ 别忘了,普通的grep可是过滤不出来的

✅️ grep -E 或者用 egrep

perl正则#

📌 perl语言正则表达式-熟悉

其实就是把我们刚才讲的正则变的更加的精简一点

  • grep -P 支持perl语言正则
  • ⚠️ egrep -P 报错

📌 前面都有撬棍

\w 里面也包括数字,字母,下划线,谨慎用

Terminal window
grep -P '\w+' re.txt
# \w 匹配字母、数字、下划线

linux中匹配空的字符,使用正则表示,'\s',同时鼠标选中将会有意想不到的结果

Terminal window
grep -P '\s' re.txt
# \s 匹配空白字符(空格、tab等)

📌 前面都有撬棍

Perl正则含义等价基础正则
\d匹配数字[0-9]
\D匹配非数字[^0-9]
\w匹配字母数字下划线[a-zA-Z0-9_]
\W匹配非字母数字下划线[^a-zA-Z0-9_]
\s匹配空白字符空格/tab等
\S匹配非空白字符非空格/tab等


总结#

📌 基础正则 vs 扩展正则 vs perl正则

  • 基础正则: grep 直接用, ^ $ . * .* [] [^] \
  • 扩展正则: egrep / grep -E, 多了 + | () {} ?
  • perl正则: grep -P, 最精简, \d \w \s

⚠️ 过滤时推荐使用单引号包裹正则表达式 ✅️ 实际生产中 egrep 用得最多

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

三剑客-grep正则
https://www.kpyun.fun/posts/basics/core/core11/
作者
久棹
发布于
2025-08-05
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
久棹
只要胆子大,天天寒暑假!
公告
欢迎来到久棹的技术小站!本站专注 Linux 运维学习笔记分享,如有问题欢迎交流探讨 🎉
分类
标签
站点统计
文章
98
分类
11
标签
203
总字数
244,453
运行时长
0
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.13.5
文章许可
CC BY-NC-SA 4.0

文章目录