05_Shell三剑客

一、Shell三剑客概述

1. Shell三剑客

Shell三剑客是指grepsedawk这三个在Linux/Unix系统中常用的命令行工具。

面试题:grep、sed、awk有何区别?

在运维工作中,我会根据不同的需求选择合适的工具:当需要简单查找时用 grep,批量修改文件时用 sed,处理复杂的日志或统计数据时使用 awk。

2. Shell三剑客适用场景

① 日志处理与搜索:使用 grep 搜索关键词,结合 sed 和 awk 进行进一步处理和分析。

② 配置文件管理:使用 sed 进行批量修改、添加或删除配置项。

③ 数据提取与转换:利用 awk 提取、分析和转换结构化文本数据,处理 CSV、JSON 等格式。

④ 监控与报警:使用 grep、sed 和 awk 提取关键信息生成监控报告,监控系统状态和性能。

⑤ 日常运维任务:自动化任务如查找过期文件、清理日志、统计日志大小等。 sed 和 awk

⑥ 系统管理:使用 sed 和 awk 处理系统状态信息,如用户信息、进程信息、磁盘使用情况等。

三者区别

工具类型功能定位输出方式是否可修改文件
grep文本搜索工具查找匹配行输出匹配行(可加 -o 打印匹配部分)❌(只读)
sed流编辑器查找、替换、删除、插入输出修改后的文本(可 -i 修改文件)✅(可用 -i 直接修改)
awk文本处理语言模式匹配、数据处理、报表生成灵活输出,可做计算❌(默认只输出结果,可重定向覆盖文件)

3. Shell三剑客执行说明

grep、sed及awk在处理数据时,都是按行进行处理。

二、Shell三剑客之grep指令

1. grep基本语法

grep主要作用:过滤来自一个文件或标准输入匹配模式内容。

基本语法:grep [OPTION]... PATTERN [FILE]...

支持的正则描述
-E,--extended-regexp模式是扩展正则表达式(ERE) => 字符簇、()、|或
-P,--perl-regexp模式是Perl正则表达式 => \d、\w、\s
-i,--ignore-case忽略大小写
-w,--word-regexp模式匹配整个单词(精确匹配)
-v,--invert-match取反
输出控制描述
-n,--line-number打印行号
-h,--no-filename不输出文件名,在多文件中搜索关键词,但只关心内容 grep -h apple file1.txt file2.txt
-l,--files-with-matches只显示匹配的文件名,一般多于-r参数一起使用 -rl
-o,--only-matching只打印匹配的内容
-r,--recursive递归目录
-c,--count统计匹配行数

2. grep案例演示

在文件中搜索包含单词 "example" 的行,是整个单词,而不是一个单词的一部分

# 数据准备
cat <<- EOF >demo.txt
Hello, this is an example file.
It contains someexample  lines of text.
Let's use grep to search for specific patterns.
EOF

cat <<- EOF >demo2.txt
Hello, this is an example file.
It contains someexample  lines of text.
Let's use grep to search for specific patterns.
EOF

[root@node1 /scripts/day07]# grep -w "example" demo.txt
Hello, this is an example file.

# 一次在多个文件中去查找
[root@node1 /scripts/day07]# grep "example" demo.txt demo2.txt
demo.txt:Hello, this is an example file.
demo.txt:It contains someexample  lines of text.
demo2.txt:Hello, this is an example file.
demo2.txt:It contains someexample  lines of text.

# 不想在前面显示有文件名
[root@node1 /scripts/day07]# grep -h "example" demo.txt demo2.txt
Hello, this is an example file.
It contains someexample  lines of text.
Hello, this is an example file.
It contains someexample  lines of text.

命令作用:

执行结果:

关键参数:

注意事项:

/etc/fstab /etc/lvm/archive/cs_00000-1813831750.vg /etc/lvm/backup/cs


**关键参数:**

**注意事项:**

注:\n代表换行符

101,Tom,CEO
102,Rose,CTO
106,Eric,CSO
107,Susan,CCO
103,Alex,COO
104,Jack,CFO
105,Jennifer,CIO
101,Tom,CEO
106,Eric,CSO
107,Susan,CCO
102,Rose,CTO
103,Alex,COO
104,Jack,CFO
105,Jennifer,CIO
101,Tom,CEO
106,Eric,CSO
107,Susan,CCO
103,Alex,COO
104,Jack,CFO
105,Jennifer,CIO

101,Tom,CEO
102,Rose,CTO
103,Alex,COO
104,Jack,CFO
105,Jennifer,CIO
102,Rose,CTO

101,Tom,CEO
102,Rose,CTO
106,Smith,CSO
107,Susan,CCO
103,Alex,COO
104,Jack,CFO
105,Jennifer,CIO

101,Tom,CEO
102,Rose,CTO
106,Smith,CSO
107,Susan,CCO
103,Alex,COO
104,Jack,CFO
105,Jennifer,CIO

注意事项:

删除指定行文本。

这个功能也是非常得有用,比如我们想删除文件中的某些行,以前最常用的是vi或vim命令,但现在我们知道了sed命令,就应该使用这个高逼格的命令完成任务了。

这里我们需要用到一个sed命令;

地址范围含义
10对第10行操作
10,20对10到20行操作,包括第10,20行
1~2first\~step,对1,3,5,7.....行操作
10,\$对10到最后一行(\$代表最后一行)操作,包括第10行
/Tom/对匹配Tom的行操作
/Tom/,/Alex/对匹配Tom的行到匹配Alex的行操作
/Tom/,\$对匹配Tom的行到最后一行操作
1,/Alex/对第1行到匹配Alex的行操作

案例1:

命令说明:这个单行删除想必大家能理解,指定删除第2行的文本

101,Tom,CEO 103,Alex,COO 104,Jack,CFO 105,Jennifer,CIO


**注意事项:**



101,Tom,CEO

102,Rose,CTO
104,Jack,CFO

101,Tom,CEO

注意事项:

命令说明:在sed软件中,使用正则的格式和awk一样,使用2个"/"包含指定的正则表达式,即"/正则表达式/"。

101,Tom,CEO 103,Alex,COO 104,Jack,CFO 105,Jennifer,CIO

101,Tom,CEO 102,Rose,CTO 103,Alex,COO 105,Jennifer,CIO


**注意事项:**

命令说明:这是正则表达式形式的多行删除,也是以逗号分隔2个地址,最后结果是删除包含"Tom"的行到包含"Alex"的行


101,Tom,CEO
105,Jennifer,CIO

111
22
666
777
@@@
@@@

103,Alex,COO
104,Jack,CFO

注意事项:

命令说明:在地址范围"2,3"后面加上! 如果不加"!"表示删除第2行和第3行, 加上"!"的结果就是除了第2行和第3行以外的内容都删除

102,Rose,CTO

102,Rose,CTO 103,Alex,COO 104,Jack,CFO 104,Jack,CFO

11 22 33

33 22 11

#!/bin/bash

}

_=/etc/profile.d/itwurevtxt.sh

33 22 11


**注意事项:**



sed修改操作,我们最常见的操作就是改配置文件,改参数等等  
首先说一下按行替换,这个功能用的很少,所以大家了解即可。这里用到的sed命令是:"c":用新行取代旧行,记忆方法:c的全拼是change,意思是替换。

命令说明:使用sed命令c将原来第2行内容替换成106,Smith,CSO,整行替换

接下来说的这个功能,有工作经验的同学应该非常的熟悉,因为使用sed软件80%的场景就是使用替换功能。

这里用到的sed命令,选项:

"s":单独使用-->将每一行中第一处匹配的字符串进行替换-->sed命令 "g":每一行进行全部替换-->sed命令s的替换标志之一(全局替换),非sed命令 "i":不区大小写


sed软件替换模型



路径替换式
s#/home#/root#g

g:global全局替换
sed本身按照进行操作的,如果在1行中有多个要替换的关键词,不加g,则代表只替换满足条件第一个关键词;如果添加g,则代表替换满足条件的所有关键词!

101,TCom,CEO
102,RoCse,CTO
103,AlCex,COO
104,Jack,CFO
105,Jennifer,CIO

101,Tom,cEO
102,Rose,cTO
103,Alex,cOO
104,Jack,cFO
105,Jennifer,cIO

101,Tcom,cEO
102,Rocse,cTO
103,Alex,cOO
104,Jack,cFO
105,Jennifer,cIO

101,TC@m,CE@
102,R@Cse,CT@
103,AlCex,C@@
104,Jack,CF@
105,Jennifer,CI@

101,TC@m,CE@
102,R@Cse,CT@
103,AlCex,C@@
104,Jack,CF@
105,Jennifer,CI@

注意事项:

sed软件的()的功能可以记住正则表达式的一部分, 其中,\1为第一个记住的模式即第一个小括号中的匹配内容, \2第二个记住的模式,即第二个小括号中的匹配内容, sed最多可以记住9个

aa:1 aa:2 aa:3 aa:4 aa:5 aa:6 aa:7 aa:8 aa:9 aa:10

aa:1 aa:2 aa:3 aa:4 aa:5 aa:6 aa:7 aa:8 aa:9 aa:10

user1:x:1003:1003::/home/user1:/bin/bash user2:x:1004:1004::/home/user2:/bin/bash user3:x:1005:1005::/home/user3:/bin/bash


**注意事项:**



这个功能也是非常得有用,比如我们想查看文件中的某些行,以前最常用的是cat或more或less命令等,但这些命令有些缺点,就是不能查看指定的行。而我们用了很久的sed命令就有了这个功能了。而且我们前面也说过使用sed比其他命令vim等读取速度更快!

这里我们需要用到1个sed命令

"p":输出指定内容,但默认会输出2次匹配的结果,因此使用-n选项取消默认输出,记忆方法:p的全拼是print,意思是打印。

案例1:

命令说明:选项-n取消默认输出,只输出匹配的文本,大家只需要记住使用命令p必用选项-n。

101,Tom,CEO
102,Rose,CTO
102,Rose,CTO
103,Alex,COO
104,Jack,CFO
105,Jennifer,CIO

102,Rose,CTO

注意事项:

命令说明:查看文件的第2行到4行,使用地址范围"2,4"。取行就用sed,最简单

102,Rose,CTO 103,Alex,COO 104,Jack,CFO


**注意事项:**

注意:起始值~步长
命令说明:打印文件的1,3,5行。~代表步长


101,Tom,CEO
103,Alex,COO
105,Jennifer,CIO

101,TCom,CEO
102,RoCse,CTO
104,Jack,CFO

注意事项:

101,TCom,CEO 102,RoCse,CTO 103,AlCex,COO 104,Jack,CFO 105,Jennifer,CIO

命令说明:不指定地址范围,默认打印全部内容。


**注意事项:**

命令说明:打印含CTO的行


103,Alex,COO

注意事项:

命令说明:打印含CTO的行到含CFO的行。

101,Tom,CEO 102,Rose,CTO 103,Alex,COO 104,Jack,CFO

11 22

11 22


**注意事项:**

命令说明:使用特殊符号"="就可以获取文件的行号,这是特殊用法,记住即可。从上面的命令结果我们也发现了一个不好的地方:行号和行不在一行。 

1
101,Tom,CEO
2
102,Rose,CTO
3
103,Alex,COO
4
104,Jack,CFO
5
105,Jennifer,CIO

案例9:

命令说明:打印1,2,3行的行号,同时打印输出文件中的内容

1 101,Tom,CEO 2 102,Rose,CTO 3 103,Alex,COO 104,Jack,CFO 105,Jennifer,CIO



作用:awk可以完成复杂的数据分析,如日志分析等等。


awk不仅仅是Linux系统中的一个命令,更可以理解为它是**一种编程语言**,可以用来处理数据和生成报告(csv)。处理的数据可以是一个或多个文件,可以是来自**标准输入**,也可以通过管道获取标准输入,awk可以在命令行上直接编辑命令进行操作,也可以编写成awk程序来进行更为复杂的运用。本章主要讲解awk命令的运用。


awk指令是由模式,动作,或者模式和动作的组合组成。

模式既pattern,可以由表达式组成,也可以是两个正斜杠之间的正则表达式。比如`NR==1`,这就是模式,可以把他理解为一个条件。


动作即action,是由在大括号里面的一条或多条语句组成,语句之间使用**分号隔开**。


![](/assets/feishu-images/f1f725d5697d3be2249afcc7.png)

awk处理的内容可以来自标准输入(<),一个或多个文本文件或管道。

![](/assets/feishu-images/7ecafb3b058cf5ad84ee77d1.png)



模式和动作的详细介绍我们放在后面部分,现在大家先对awk结构有一个了解。

awk操作流程:


案例1:基本模式与动作






22
22

注意事项:

96.9

1------>3------->root 2------>3------->admin 3------>3------->user

1,3,root 2,3,admin 3,3,user


**注意事项:**


6

注意事项:

bin:x:1:1:bin:

命令说明: BEGIN:开始模块,在awk开始处理数据之前执行1次

在每行的开始先打印输出NR(记录号行号),并打印出每一行$0(整行)的内容。 我们设置RS(记录分隔符)的值为“/”,表示一行(记录)以“/”结束 在awk眼中,文件是从头到尾一段连续的字符串,恰巧中间有些\n(回车换行符),\n也是字符哦。


> 
> 
> 
> 
> 
> 
> 
> 
> 

案例2:NR记录行号


命令说明:
$0表示整行或者说整个记录

基本语法:

分隔符,需不需要根据某个符号提取某1列,默认是空格或tab


NR存放着每个记录的号(行号)读取新行时候会自动+1

RS是输入数据的记录的分隔符,简单理解就是可以指定每个记录的结尾标志。

RS作用就是表示一个记录的结束

当我们修改了RS的值,最好配合NR(行)来查看变化,也就是修改了RS的值通过NR查看结果,调试awk程序。

ORS输出数据的记录的分隔符


每条记录都是由多个区域(field)组成的,默认情况下区域之间的分隔符是由空格(即空格或制表符)来分隔,并且将分隔符记录在内置变量FS中,每行记录的区域数保存在awk的内置变量NF中。

![](/assets/feishu-images/a7846708358757c1ccf7892a.png)



OFS输出字段(列)分隔符



案例1:指定分隔符

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin



1---->root
2---->bin
3---->daemon
4---->adm
5---->lp
6---->sync
7---->shutdown
8---->halt
9---->mail
10---->uucp

root----->x
bin----->x
daemon----->x

aa:11:aaaaaa
bb:22-bbbbb
cc@33xccccc



命令说明:
以:(冒号)为分隔符,显示第2行到第5行之间的第一区域和第三区域。

注意事项:

1234567890 234567890 634567890


**注意事项:**



awk模式与动作

接下来就详细介绍下,awk的模式都有几种:





案例1:awk正则表达式匹配整行

获取以root开头的行

或
-----------------------------------------------

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

root:x:0:0:root:/root:/bin/bash

127.0.0.1
192.168.50.213

注意事项:

root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

19

5


**注意事项:**

注意事项:

root:x:0:0:root bin:x:1:1:bin daemon:x:2:2:daemon adm:x:3:4:adm lp:x:4:7:lp


练习题2:显示Xiaoyu的名字和ID号码,并以逗号隔开

Xiaoyu,390320151

练习题3:显示所有以41开头的ID号码的人的全名和ID号码


练习题4:显示所有以一个D或X开头的名字的,全名

练习题5:显示所有ID号码最后一位数字是1或5的人的全名


案例4:取出指定网卡的ip地址

192.168.50.213

案例5:取出常用服务端口号

说明:linux下面服务与端口信息的对应表格在/etc/services里面。此文件大约从23行开始基本上每一行第一列是服务名称,第二列是端口/协议。


**注意事项:**



![](/assets/feishu-images/3915f05b33cdbea1c5122151.png)

![](/assets/feishu-images/fa7f7ea91a885b56eabc6429.png)




案例1:可以使用BEGIN设定表头信息

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

注意事项:


**注意事项:**

0.5
0.6

3.33333

3.33

作用:与BEGIN相呼应,在awk处理文件结束后,会自动触发END模块(只会触发1次)

123


**注意事项:**

16

16

注意事项:


**注意事项:**



语法

案例1:统计系统用户数量

uid的大小在1到1000之间,它在/etc/passwd中就有保存uid值

18

18


案例2:条件判断两个值比较,如果正确则输出0,错误为1

0
1

案例3:统计系统用户中能登录用户数和不能登录用户数


案例4:统计出超管数、系统用户数和注册用户数

语法


案例:打印1到5

1
2
3
4
5

5050

1
2
3

分类

}' --------------------------------------------

10

2



}'

--------------------------------------------

10 20

10




}'

id下标存在

}' --------------------------------------- 10



统计`/etc/passwd`中单词出现频率

#!/bin/bash


        for(i=1;i<=NF;i++){
            }
            arr[$i]++
        }
    }END{
        asorti(arr)
        }

本文由飞书云文档同步生成。涉及命令、SQL、配置示例时,请以飞书源文档和实际环境执行结果为准。