文本编辑三剑客(grep)

目录

正则表达式

元字符

grep

案例

我在编写脚本的时候发现,三个文本编辑的命令(grep、sed、awk,被称为文本编辑三剑客,我习惯叫它三巨头)用的还挺多的,说实话我一开始学的时候也有些懵,主要是太多太杂,有那么个别些还有点难懂,最近恰好有时间,索性把三剑客相关的东西都整理出来,方便日后生疏了再回顾一下,顺便和大家一起交流学习。

在学三巨头之前,首先要知道正则表达式

正则表达式

什么是正则表达式?正则表达式又称规则表达式,通常用于判断语句中,是一种用于匹配字符串中字符组合的模式,一般由普通字符(字母、数字)与特殊字符(元字符)组成

我们之前讲过文件测试,是用 [ ]或者 test 实现的,还有学习 if 语句的时候,也是通过 [ ] 来进行条件判断。正则表达是也是用 [ ] 来做字符串匹配的,只不过,它所匹配的样式种类更多更齐全。

正则表达式直接使用的匹配规则是

\[ 变量 =\~ 正则式 \]

一个例子,我们定义一个变量 num 看看它与正则式是否匹配,输出结果是匹配

=~ 是匹配正则式的固定搭配,测试的时候不要忘了加

0-9\] 是检验变量里是否有0-9的数字 这里你可能会疑问,如果num = s2d2j93 这种数字字母穿插的,判断结果是什么呢? 答案是,仍然输出匹配, 因为 \[0-9\] 只看你的变量中有没有数字,我们之前在编写shell脚本的时候也遇到,一个猜数字的脚本,如何避免输入除数字外的其他字符呢? 现在可以得到解答了,只需要验证变量是否 =\~ \^\[0-9\]+$ 就可以了。 我们都知道,在grep命令中,\^是以什么什么开头,而$是以什么什么结尾,这样一组合,是不是就通俗易懂了,以数字开头以数字结尾,那不就是匹配纯数字的字符串吗? 我们来正反都验证一下,结果不出我所料(doge ![](https://i-blog.csdnimg.cn/direct/35fa33ac0d92480995919a5d6ee047db.png) #### 元字符 通过上面这个例子,想必应该对正则有了个大致的了解,其实并不困难,主要就是选项很多很杂,常见的元字符有 **\[ \]**:定义一个字符类,匹配括号内的任意一个字符。 例如, \[abc\] 可以匹配 "a"、"b" 或 "c" **.**:匹配除换行符之外的任何单个字符 例如, a.c 可以匹配 "abc"、"a1c"、"a@c" 等 **\***:匹配前面的元素零次或多次 例如, ab\*c 可以匹配 "ac"、"abc"、"abbc"、"abbbc" 等 **+**:和 \* 一样,但只能匹配前面的元素一次或多次,不包括零次 所以 ab+c 只可以匹配 "abc"、"abbc"、"abbbc" 等,不能匹配 "ac" **?**:匹配前面的元素零次或一次 例如,ab?c 可以匹配 "ac" 或 "abc" **\^**:匹配字符串的开始。 例如, \^abc 匹配以 abc 开头的字符串。 **$**:匹配字符串的结束。 例如, abc$ 匹配以 abc 结尾的字符串。 **\[\^\]**:定义一个否定字符类,匹配不在括号内的任意一个字符。 例如, \[\^abc\] 匹配除了 "a"、"b" 和 "c" 之外的任意字符。 **\|**:或操作符,匹配两者中的任意一个。 例如,正则表达式 abc\|def 可以匹配 "abc" 或 "def"。 **()**:分组,用于将多个元素组合成一个单元,并捕获匹配的文本。 例如, (abc)+ 可以匹配 "abc"、"abcabc" 等。 \\{n\\}:匹配前面的元素恰好 n 次。 例如, a{3} 可以匹配 "aaa"。 \\{n,\\}:匹配前面的元素至少 n 次。 例如, a{3,} 可以匹配 "aaa"、"aaaa"、"aaaaa" 等。 \\{n,m\\}:匹配前面的元素至少 n 次,但不超过 m 次。 例如, a{3,5} 可以匹配 "aaa"、"aaaa"、"aaaaa"。 \\d:匹配任意一个数字字符(0-9)。 例如, \\d 可以匹配 "1"、"2"、"3" 等。 \\w:匹配任意一个字母、数字或下划线字符。 例如, \\w 可以匹配 "a"、"1"、"_" 等。 \\s:匹配任意一个空白字符(空格、制表符、换行符等)。 例如, \\s 可以匹配空格、制表符等。 \\D:匹配任意一个非数字字符。 例如, \\D 可以匹配 "a"、"@"、" " 等。 其实还有一部分没有列出,基本上用不到,可能用到的就这么多了,万一有遗漏我后续会补上。 正则表达式的规则就这么多,大多数情况都是搭配三巨头使用的,所以说接下来就可以开始学习三巨头了,搭配 grep、sed、awk 等命令使用的时候,含义是不变的,但是使用的符号会有点出入,所以接下来就通过大量的实例来进行讲解。 ### grep 首先肯定是从我们最为熟知,也是使用过的 grep 命令开始,grep命令最常用的参数可能就是 grep -v 还有 grep -i 了,这两个都是它的基本选项,我们接下来要了解它的输出控制选项,所以说要和正则表达式搭配使用呢,一个负责筛选过滤,一个负责控制输出的内容。常用的有 -E :开启扩展的正则表达式 -c :计算找到 '搜寻字符串' 的次数 -o :只显示被模式匹配到的字符串 -w:匹配整个单词 -n :输出行号 我创建了一个 123.txt 文件,用来测试各种案例,你们可以直接复制粘贴使用 #123.txt his is a test file for grep command. t contains various patterns and special characters. asic characters: abc, def, ghi 2. Digits: 123, 456, 789 3. Special characters: ., *, +, ?, ^, $, [, ], {, }, |, (, ) 4. Word boundaries: start, end, middle on-word characters: @, #, %, &, ! scaped characters: \., \*, \+, \?, \^, \$, \[, \], \{, \}, \|, \(, \) ultiple lines with the same pattern: pattern pattern pattern Case sensitivity: Case, case, CASE Whole word matching: word, sword, reword hole line matching: This is a whole line. ontext lines: This is line before the match. his is the matching line. This is line after the match. ile names: file1.txt, file2.txt, file3.txt Directory names: dir1, dir2, dir3 xclude patterns: exclude this line Include patterns: include this line ecursive patterns: ./dir1/file1.txt ./dir2/file2.txt ./dir3/file3.txt olor highlighting: highlight this ount matching lines: count this line Matching groups: group1, group2, group3 on-matching groups: nongroup1, nongroup2, nongroup3 ll lol lool loool loooool looooool looooooool loooooooooooooooooool #### 案例 先来个简单的吧,找出 hole 并打印行号 grep -n 'hole' 123.txt 打印出来有两个,此时我们加一个w,就可以只显示 hole 这个单词的了 ![](https://i-blog.csdnimg.cn/direct/b0f1a85faa3d46bb82f7e9258cb5b529.png) 那么相反,如果我查找不含 hole 的 只需要加上 -v 就可以了,也可以通过 \[\^\] 来筛选前面不含w的 grep -n '\[\^w\]hole' (还有别的方法可以自己测试,比如\[\^a-z\]hole,直接让前面不带字母等等) 接下来需要查找 test 或者 text 并打印行号(-n 之后的例子就不特别说明了) grep -n 'te\[sx\]t' 123.txt ![](https://i-blog.csdnimg.cn/direct/036ac3963d124b49b297f87725926c2a.png) 这里用到了\[ \] ,匹配 s 或 x ,test 和 text 都被输出了出来 我们也可以通过 '.' 任意字符,来完成这个操作 grep -n 'te.t' 123.txt 有几个 . 就代表中间有几个任意字符 ![](https://i-blog.csdnimg.cn/direct/1c0c95f470a148b49b861bd460673685.png) 我们再来查找一下有数字的行 grep -n '\[0-9\]' 123.txt ![](https://i-blog.csdnimg.cn/direct/3a0dc44d0ea44772b657e0c38e452fa6.png) 下面我们来查找以数字开头的行 grep -n '\^\[0-9\]' 123.txt ![](https://i-blog.csdnimg.cn/direct/2af49ecc37b94066a50688ccad60e0bd.png) 以此类推,假如以字母开头,那就是 \^\[a-z

那么,现在有一个疑问,假如要查找不以字母开头的呢?要知道,除了字母数字,还有特使字符和空格等开头的行,而且字母也是有大小写的,此时该怎么办呢?

原理也差不多,[^] 是过滤不含某些内容的,那我们就不含字母

grep -n '^[^a-zA-Z]' 123.txt 这个正则表达式同时过滤了小写字母和大写字母,如果连数

字也要过滤掉,那么就在a-zA-Z的随便哪个位置加上0-9就可

以了,顺序无所谓的,但最好按照a-z A-Z 的顺序,不然不确

定会不会出现什么问题

附上过滤数字的运行截图

如果想查找以字母或数字结尾的,那么和以什么什么为开头的一样,在 [ ] 后面加上 $ 就可以了,如图,就不细说了↓

grep '[789]$' 123.txt 过滤出来是只有9是亮着的,因为 [ ] 匹配了 7 或者 8 或者 9 的字符串,那么,问一个简单的问题,假如我就非要,查找789这一个整体结尾的行,该怎么办呢?

额外提一句,grep -n '^$' 123.txt 代表输出空行的行

接下来,测试文件里的那么多 looool ,要派上用场了

回过头来看咱前面提到的元字符,是不是突然想到了什么

grep -n 'lo*l' 123.txt grep -n 'lo+l' 123.txt

它们的输出结果应该 * 有ll,而 + 没有,除此之外输出结果应该一致

验证一下

一个新的问题出现了,为什么 grep -n 'lo+l' 123.txt 没有任何结果输出?我仅仅是将 * 号改成了+号,按理来说不可能出现语法错误啊?

我们来排错一下, grep -v 'lo+l' 123.txt

整个文档都被输出出来了,说明文档里没有能与 'lo+l' 匹配的行,我们试着去文档里创捷新的一行,只有lo+l

保存并退出, 再来一次 grep -n 'lo+l' 123.txt

真相了家人们,grep过滤的时候,读取的是 "lo+l" 这一整个字符串,+ 并没有被当作是元字符,我们给它加上一个 \ 转义符看看

这下成功了,得到想要的结果了,再回过头来看,是不是和 lo*l 的输出只相差了一个 ll

现在,我只想查找,ll之间夹着 3-6 个 o 的行

grep -n 'lo\{3,6\}l' 123.txt

其他的需求也可以依葫芦画瓢,比如 至少 5个o 那就是 grep -n 'lo\{5,\}l' 123.txt , 转义符不要忘记

grep过滤的功能远不止在过滤文件内容,还可以搭配管道符号,再写入脚本,对脚本进行很大的优化

比如我们都知道,ifconfig ens33 是查看网卡的内容

那么,我们是不是可以通过一些条件约束,使之只显示我们需要的内容呢?比如说ip地址

很简单啊,过滤inet开头那一行,但是这样的输出结果,无法直接作为纯数字传递给脚本参数等进行处理,我们需要仅显示ip地址等

那么就需要过滤含有 [0-9].[0-9].[0-9].[0-9] 的行

ifconfig ens33 |grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+"

学好三巨头还是要靠熟记各种参数元字符的含义并巧妙应用,做到事半功倍的效果

另外还有sed 和 awk 我之后整理了差不多再进行讲解

相关推荐
s_little_monster11 分钟前
【Linux】进程信号的捕捉处理
linux·运维·服务器·经验分享·笔记·学习·学习方法
一大Cpp22 分钟前
Ubuntu与本地用户交流是两种小方法
linux·运维·ubuntu
小王不会写code26 分钟前
CentOS 7 镜像源失效解决方案(2025年)
linux·运维·centos
zyplanke29 分钟前
CentOS Linux升级内核kernel方法
linux·运维·centos
go_bai1 小时前
Linux环境基础开发工具——(2)vim
linux·开发语言·经验分享·笔记·vim·学习方法
这儿有一堆花3 小时前
Kali Linux 2025.1a:主题焕新与树莓派支持的深度解析
linux·运维·服务器
Kusunoki_D3 小时前
使用 VIM 编辑器对文件进行编辑
linux·编辑器·vim
东方佑6 小时前
自动调整PPT文本框内容:防止溢出并智能截断文本
linux·运维·powerpoint
zhougl9967 小时前
html处理Base文件流
linux·前端·html