高级DBA运维
成长之路

第8章:三剑客命令说明

文章目录

1.  三剑客sed命令说明

sed - stream editor for filtering and transforming text 
可以进行文本编辑,文本过滤处理
主要用于处理文本文件,对一些配置文件进行编辑修改
包括:文本文件信息,日志文件信息(grep过滤,awk分析),配置文件信息(sed)

2. sed命令使用方式和工作原理

标准格式 sed [选项] [sed指令] [文件信息]
举例说明 sed -i.bak 's#oldboy#oldgirl#g' oldboy.txt

工作原理: 
01. 按行进行过滤
02. 将过滤出来的一行内容放入到模式空间中
03. 会有默认输出(-n)
04. 一行处理完会继续处理下一行

3. sed命令使用方法

环境准备:
cat >person.txt<<EOF
101,oldboy,CEO
102,zhaoyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
EOF

—3.1 查询信息

——3.1.1 单行查找内容

1)根据字符内容进行过滤
[root@linux ~]# sed -n '/Alex/p' person.txt
103,Alex,COO

2)根据行号信息进行过滤
[root@linux ~]# sed -n '3p' person.txt
103,Alex,COO
[root@linux ~]# sed -n '4p' person.txt
104,yy,CFO

——3.1.2 多行查找内容

1)按照行号信息进行过滤
[root@linux ~]# sed -n '2,4p' person.txt 
102,zhaoyao,CTO
103,Alex,COO
104,yy,CFO

2)按照内容信息进行过滤
[root@linux ~]# sed -n '/oldboy/,/yy/p' person.txt 
101,oldboy,CEO
102,zhaoyao,CTO
103,Alex,COO
104,yy,CFO

3)过滤不连续的多行信息(按照过滤的字符)
sed -n '/Alex/p' person.txt 
sed -n '/feixue/p' person.txt 
sed -n '/Alex/p;/feixue/p' person.txt

3)过滤不连续的多行信息(按照行号)
sed -n '3p;6p' person.txt

——3.1.3 查询显示行号

[root@linux ~]# sed '=' person.txt|xargs -n2 
1 101,oldboy,CEO
2 102,zhaoyao,CTO
3 103,Alex,COO
4 104,yy,CFO
5 105,feixue,CIO

—3.2 增加信息

——3.2.1 向文件指定行的后面增加信息

[root@linux ~]# sed '4a oldgirl' person.txt 
101,oldboy,CEO
102,zhaoyao,CTO
103,Alex,COO
104,yy,CFO
oldgirl
105,feixue,CIO
106,yy,CFO

[root@linux ~]# sed '/Alex/a oldgirl02' person.txt 
101,oldboy,CEO
102,zhaoyao,CTO
103,Alex,COO
oldgirl02
104,yy,CFO
105,feixue,CIO
106,yy,CFO

[root@linux ~]# sed '4a oldgirl01\noldgirl02' person.txt 
101,oldboy,CEO
102,zhaoyao,CTO
103,Alex,COO
104,yy,CFO
oldgirl01
oldgirl02
105,feixue,CIO
106,yy,CFO

[root@linux ~]# sed '$a oldgirl01\noldgirl02' person.txt 
101,oldboy,CEO
102,zhaoyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
106,yy,CFO
oldgirl01
oldgirl02
说明: $符号表示最后一行信息

——3.2.2 向文件指定行的前面增加信息

[root@linux ~]# sed '4i oldgirl01\noldgirl02' person.txt 
101,oldboy,CEO
102,zhaoyao,CTO
103,Alex,COO
oldgirl01
oldgirl02
104,yy,CFO
105,feixue,CIO
106,yy,CFO

—3.3 删除信息

——3.3.1 按照行号进行单行或多行删除

[root@linux ~]# sed '3,4d' person.txt 
101,oldboy,CEO
102,zhaoyao,CTO
105,feixue,CIO
106,yy,CFO

——3.3.2 按照信息进行单行或多行删除

[root@linux ~]# sed -r '/Alex|feixue/d' person.txt 
101,oldboy,CEO
102,zhaoyao,CTO
104,yy,CFO
106,yy,CFO

——3.3.3 删除文件空行信息

[root@linux ~]# sed -n '/^$/d' person.txt
或者
[root@linux ~]# sed -n '/^$/!p' person.txt
101,oldboy,CEO
102,zhaoyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
106,yy,CFO
说明: 利用!p表示对输出的内容信息进行取反

——3.3.4 真正对文件内容进行修改编辑

[root@linux ~]# sed -ri.bak '/Alex|feixue/d' person.txt 
[root@linux ~]# cat person.txt 
101,oldboy,CEO
102,zhaoyao,CTO
104,yy,CFO
106,yy,CFO

-i 参数使用注意事项
a. -i参数一定编写在所有参数之后
b. -i参数在使用时一定不能和-n参数结合使用

一种情况: -i参数写到所有参数的前面了
sed -i.bakr '/Alex|feixue/d' person.txt
 
二种情况: -i参数会将屏蔽输出的信息放入到文件中
[root@linux ~]# sed -rn '7s#(.*=).*#\1disabled#gp' /etc/selinux/config 
SELINUX=disabled
[root@linux ~]# sed -rni.bak '7s#(.*=).*#\1disabled#gp' /etc/selinux/config 
[root@linux ~]# cat /etc/selinux/config 
SELINUX=disabled

—3.4 修改信息

——3.4.1 单行进行整体修改

[root@linux ~]# sed '3c oldboy' person.txt

——3.4.2 多行进行整体修改

[root@linux ~]# sed -e '3c oldboy' -e '6c oldgirl' person.txt
101,oldboy,CEO
102,zhaoyao,CTO
oldboy
103,Alex,COO
104,yy,CFO
oldgirl
105,feixue,CIO
106,yy,CFO
说明:
c 表示多指定行进行整体修改
-e 可以用于识别sed命令中的多个指令

——3.4.3 单行或多行进行部分内容修改

根据内容进行修改调整:
a.按照指定行进行修改调整
sed '4s#Alex#goodman#g' person.txt
sed '/103/s#Alex#goodman#g' person.txt

b.利用正则符号进行匹配,再做调整(后向引用前向)
[root@linux ~]# echo 123456|sed -r "s#(.*)#<\1>#g"
<123456>
[root@linux ~]# echo 123456|sed -r "s#.*#<&>#g"
<123456>
[root@linux ~]# echo 123456|sed -r 's#(..)(..)(..)#<\1><\2><\3>#g'
<12><34><56>
[root@linux ~]# echo 123456|sed -r 's#([0-9]{2})#<\1>#g'
<12><34><56>

——3.4.4 批量修改多个文件扩展名

touch oldboy{01..10}.jpg
需要将oldboy01.jpg..oldboy10,jpg所有文件扩展名改写为以png结尾
利用sed命令进行批量
提示:
mv oldboy01.jpg oldboy01.png
交给bash进行修改

第一个历程: 将需要修改的文件进行查找过滤
[root@linux ~]# find /root/ -type f -name "oldboy*jpg"
/root/oldboy01.jpg
/root/oldboy02.jpg
/root/oldboy03.jpg
/root/oldboy04.jpg
/root/oldboy06.jpg
/root/oldboy07.jpg
/root/oldboy09.jpg
/root/oldboy10.jpg
/root/oldboy05.jpg
/root/oldboy08.jpg

第二个历程: 将上面命令执行的结果交给sed命令进行处理
单行信息进行修改调整
[root@linux ~]# echo "/root/oldboy01.jpg"|sed -r 's#(.*)jpg#mv & \1png#g'
mv /root/oldboy01.jpg /root/oldboy01.png

多行信息进行修改调整
[root@linux ~]# find /root/ -type f -name "oldboy*jpg"|sed -r 's#(.*)jpg#mv & \1png#g'
mv /root/oldboy01.jpg /root/oldboy01.png
mv /root/oldboy02.jpg /root/oldboy02.png
mv /root/oldboy03.jpg /root/oldboy03.png
mv /root/oldboy04.jpg /root/oldboy04.png
mv /root/oldboy06.jpg /root/oldboy06.png
mv /root/oldboy07.jpg /root/oldboy07.png
mv /root/oldboy09.jpg /root/oldboy09.png
mv /root/oldboy10.jpg /root/oldboy10.png
mv /root/oldboy05.jpg /root/oldboy05.png
mv /root/oldboy08.jpg /root/oldboy08.png

第三个历程: 将命令输出的信息进行执行
[root@linux ~]# echo "mv person.txt.bak person.txt.bak00" 
mv person.txt.bak person.txt.bak00
[root@linux ~]# echo "mv person.txt.bak person.txt.bak00" |bash

[root@linux ~]#find /root/ -type f -name "oldboy*jpg"|sed -r 's#(.*)jpg#mv & \1png#g'|bash
[root@linux ~]# ll
-rw-r--r-- 1 root root 0 Jan 21 11:28 oldboy01.png
-rw-r--r-- 1 root root 0 Jan 21 11:28 oldboy02.png
-rw-r--r-- 1 root root 0 Jan 21 11:28 oldboy03.png
-rw-r--r-- 1 root root 0 Jan 21 11:28 oldboy04.png
-rw-r--r-- 1 root root 0 Jan 21 11:28 oldboy05.png
-rw-r--r-- 1 root root 0 Jan 21 11:28 oldboy06.png
-rw-r--r-- 1 root root 0 Jan 21 11:28 oldboy07.png
-rw-r--r-- 1 root root 0 Jan 21 11:28 oldboy08.png
-rw-r--r-- 1 root root 0 Jan 21 11:28 oldboy09.png
-rw-r--r-- 1 root root 0 Jan 21 11:28 oldboy10.png

——3.4.5 批量修改多个文件扩展名标准解法

批量修改文件名称的命令: rename
rename [options] expression replacement file...
rename '将文件内容什么做修改' '修改成什么' 要修改的文件信息
rename 'png' 'jpg' oldboy*png

利用变量信息进行修改替换文件内容
[root@linux ~]# info=oldboy
[root@linux ~]# echo oldboy|sed "s#$info#oldgirl#g"
oldgirl

—3.5 批量创建用户

(不需使用for循环脚本)
a 批量创建10个用户 useradd oldboy{01..10}
b 给每个用户设置密码 
c 需要设置随机密码 随机6位密码
d 随机密码和用户对应关系信息要保存在一个文件中
oldboy01 xasdas
oldboy02 asda9a
e 以上需求利用一条命令完成
包含useradd ,passwd,sed,touch | bash, echo, 变量 >>命令 

—3.6 企业需求测验取出IP地址信息

方法一: 利用sed
第一个历程: 如何获得IP地址
ip address show eth0

第二个历程: 将IP地址所在的行过滤出来
ip address show eth0|sed -n '3p'

第三个历程: 将一行中没有的信息进行删除
ip address show eth0|sed -n '3p'|sed -r 's#^.*net (.*)#\1#g'|sed -r 's#(.*)/24.*$#\1#g'
截取IP地址前的信息 截取IP地址后的信息
命令优化
ip address show eth0|sed -n '3p'| sed -r 's#^.*net (.*)/24.*$#\1#g'
终极优化
ip address show eth0|sed -nr '3s#^.*net (.*)/24.*$#\1#gp'

方法二: 利用grep
第一个历程: 如何获得IP地址
ip address show eth0 

第二个历程: 将IP地址所在的行过滤出来
ip address show eth0|grep "inet "

第三个历程: 取出IP地址信息
ip address show eth0|grep "inet "|grep -E "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" 

命令优化 
ip address show eth0|grep "inet "|grep -E "([0-9]+\.){3}[0-9]+"
终极优化 
ip address show eth0|grep "inet "|grep -E "([0-9]+\.?){3}" 
ip address show eth0|grep "inet "|grep -E "([0-9]+\.?){4}" -o|head -1
方法三: 利用awk 
[root@linux ~]# ip a s eth0|awk -F "[ /]+" 'NR==3{print $3}'
10.0.0.201

3.7 sed命令汇总

sed 对文件行进行操作 对文件内容进行编辑修改
参数信息
-n 取消默认输出
-i 真正修改文件数据内容
-r 读取扩展正则符号
-e 读取多个指令信息
指令信息
p 显示输出一行的内容信息
a 在一行之后添加信息
i 在一行之前添加信息
c 整行内容进行修改
d 整行内容进行删除
s###g 对文件内容进行替换修改

4. 三剑客命令awk概念说明

a 擅长对列进行操作处理
b 擅长对文件数据进行分析统计
文本文件信息、日志文件信息(最擅长)、配置文件信息

5. awk命令使用方式和工作原理

1) 查询操作
2) 排除操作
3) 替换操作(模拟替换)
4) 统计操作

命令格式:
sed [参数] '指令信息' 文件信息 
awk [选项] '模式{动作}' [文件信息] 
模式: 匹配的条件 /oldboy/
awk命令执行的逻辑
00. 在读取文件之前,执行什么动作信息 特殊模式 BEGIN
01. 按照文件中的每一行处理文件内容
02. 在读取文件之后,执行什么动作信息 特殊模式 END

6. awk命令使用方法

生成模拟环境:
cat >> ~/reg.txt<<EOF
Zhang Dandan 41117397 :250:100:175
Zhang Xiaoyu 390320151 :155:90:201
Meng Feixue 80042789 :250:60:50
Wu Waiwai 70271111 :250:80:75
Liu Bingbing 41117483 :250:100:175
Wang Xiaoai 3515064655 :50:95:135
Zi Gege 1986787350 :250:168:200
Li Youjiu 918391635 :175:75:300
Lao Nanhai 918391635 :250:100:175
EOF
每列对齐操作
cat ~/reg.txt.bak|column -t >~/reg.txt

—6.1  显示xiaoyu的姓氏和ID号码

第一历程: 根据需求找到符合条件的信息
按行查找
awk 'NR==2' ~/reg.txt
[root@linux ~]# awk 'NR==2' ~/reg.txt
Zhang Xiaoyu 390320151 :155:90:201
或者
[root@linux ~]# awk 'NR==2{print $0}' ~/reg.txt
Zhang Xiaoyu 390320151 :155:90:201

字符查找
~ 表示按列进行匹配
!~ 表示按列进行排除匹配
awk '/Xiaoyu/' ~/reg.txt 错误 
awk '$2~/Xiaoyu/' ~/reg.txt 按第2列匹配

第二历程: 满足条件的信息进行处理 
[root@linux ~]# awk 'NR==2{print $1,$3}' ~/reg.txt
Zhang 390320151
[root@linux ~]# awk 'NR==2{print $1" "$3}' ~/reg.txt
Zhang 390320151 
[root@linux ~]# awk '$2~/Xiaoyu/{print $1" "$3}' ~/reg.txt
Zhang 390320151

—6.2 姓氏是zhang的人,显示他的第二次捐款金额及他的名字

第一历程: 根据需求找到符合条件的信息 
字符查找
[root@linux ~]# awk '$1~/Zhang/' reg.txt
Zhang Dandan 41117397 :250:100:175
Zhang Xiaoyu 390320151 :155:90:201
[root@linux ~]# awk '/^Zhang/' reg.txt
Zhang Dandan 41117397 :250:100:175
Zhang Xiaoyu 390320151 :155:90:201 

第二历程: 满足条件的信息进行处理 
[root@linux ~]# awk '/^Zhang/{print $2,$4}' reg.txt
Dandan :250:100:175
Xiaoyu :155:90:201
无法取出第4列中的部分内容
[root@linux ~]# awk -F "[ :]+" '/^Zhang/{print $2,$5}' reg.txt
Dandan 100
Xiaoyu 90
[root@linux ~]# awk -F "[ :]+" '/^Zhang/{print $2,$(NF-1)}' reg.txt
Dandan 100
Xiaoyu 90

awk参数说明:
-F 用于指定awk切割列的条件信息
利用[]+ 可以将连续多个切割字符整合为一个整体

—6.3 显示所有以41开头的ID号码的人的全名和ID号码

第一历程: 根据需求找到符合条件的信息
[root@linux ~]# awk '$3~/^41/' reg.txt
Zhang Dandan 41117397 :250:100:175
Liu Bingbing 41117483 :250:100:175

第二历程: 满足条件的信息进行处理 
[root@linux ~]# awk '$3~/^41/{print $1,$2,$3}' reg.txt
Zhang Dandan 41117397
Liu Bingbing 41117483

—6.4 显示所有ID号码最后一位数字是1或5的人的全名

第一历程: 根据需求找到符合条件的信息
[root@linux ~]# awk '$3~/[15]$/' reg.txt
Zhang Xiaoyu 390320151 :155:90:201
Wu Waiwai 70271111 :250:80:75
Wang Xiaoai 3515064655 :50:95:135
Li Youjiu 918391635 :175:75:300
Lao Nanhai 918391635 :250:100:175

第二历程: 满足条件的信息进行处理 
[root@linux ~]# awk '$3~/[15]$/{print $1,$2}' reg.txt
Zhang Xiaoyu
Wu Waiwai
Wang Xiaoai
Li Youjiu
Lao Nanhai

—6.5  显示Xiaoyu的捐款,每个时都有以$开头

如$110$220$330
第一历程: 根据需求找到符合条件的信息
[root@linux ~]# awk '$2~/Xiaoyu/' reg.txt
Zhang Xiaoyu 390320151 :155:90:201

第二历程: 满足条件的信息进行处理
[root@linux ~]# awk '$2~/Xiaoyu/{print $4}' reg.txt
:155:90:201

[root@linux ~]# awk '$2~/Xiaoyu/{gsub(/:/,"$",$4);print $4}' reg.txt
$155$90$201

awk替换测试命令
[root@linux ~]# echo :155:90:201|awk '{gsub(/:/,"$",$1);print $1}' 
$155$90$201

补充: awk替换信息语法格式
awk '{gsub(//,"",$n);print $n}'
/要替换修改的信息/,"修改成什么信息",需要修改的列的信息
/:/,"$",

—6.6 awk特殊模式说明

——6.6.1 BEGIN{}

1) 再操作文件之前,执行相应操作动作
实际应用: 输出每列的表头信息
[root@linux ~]# awk 'BEGIN{print "姓","名","id","捐款记录"}{print $0}' reg.txt|column -t
姓 名 id 捐款记录
Zhang Dandan 41117397 :250:100:175
Zhang Xiaoyu 390320151 :155:90:201
Meng Feixue 80042789 :250:60:50
Wu Waiwai 70271111 :250:80:75
Liu Bingbing 41117483 :250:100:175
Wang Xiaoai 3515064655 :50:95:135
Zi Gege 1986787350 :250:168:200
Li Youjiu 918391635 :175:75:300
Lao Nanhai 918391635 :250:100:175
2) 可以进行运算
[root@linux ~]# awk 'BEGIN{print 3+2}'
5
[root@linux ~]# awk 'BEGIN{print 3-2}'
1
[root@linux ~]# awk 'BEGIN{print 3*2}'
6
[root@linux ~]# awk 'BEGIN{print 3/2}'
1.5
[root@linux ~]# awk 'BEGIN{print 3^2}'
9
[root@linux ~]# awk 'BEGIN{print 3%2}'
1
[root@linux ~]# awk 'BEGIN{print 5%3}'
2
[root@linux ~]# awk 'BEGIN{print 5**3}'
125
[root@linux ~]# awk 'BEGIN{print 2**3}'
8
[root@linux ~]# awk 'BEGIN{print 2^3}'
8

3) 修饰内置变量
[root@linux ~]# oldboy=12345
[root@linux ~]# echo $oldboy
12345
[root@linux ~]# awk -voldboy=12345 'BEGIN{print oldboy}'
12345

NF 表示一行中的最后一列信息
NR 表示行号信息 NR==
FS 表示字段分隔信息
[root@linux ~]#stat /etc/hosts|awk 'BEGIN{FS="[(/]"}NR==4{print $2}'
0644
[root@linux ~]# stat /etc/hosts|awk -vFS="[(/]" 'NR==4{print $2}'
0644

——6.6.2 END{}

1) 再操作文件之后,执行相应操作动作
实际应用: 用于输出最终结果信息
[root@linux ~]# awk '{print $0}END{print "oldboyedu57"}' reg.txt
Zhang Dandan 41117397 :250:100:175
Zhang Xiaoyu 390320151 :155:90:201
Meng Feixue 80042789 :250:60:50
Wu Waiwai 70271111 :250:80:75
Liu Bingbing 41117483 :250:100:175
Wang Xiaoai 3515064655 :50:95:135
Zi Gege 1986787350 :250:168:200
Li Youjiu 918391635 :175:75:300
Lao Nanhai 918391635 :250:100:175
oldboyedu57

—6.7 awk对数据文件信息分析处理练习

——6.7.1 统计/etc/services文件中空行数量

第一个历程: 如何进行累加运算
[root@linux ~]# i=1
[root@linux ~]# awk 'BEGIN{i=i+1;print i}'
1
[root@linux ~]# awk -vi=1 'BEGIN{i=i+1;print i}'
2
[root@linux ~]# awk -vi=2 'BEGIN{i=i+1;print i}'
3
说明:
awk -v参数可以设置变量
awk 调取变量不需要加上$
awk 默认会将字符当成变量进行调取 如果不想被识别为变量需要加上双引号
awk 进行累加运算的公式 i=i+1

第二个历程: 将空号找出来,进行累加运算
[root@linux ~]# awk '/^$/{i=i+1;print i}' /etc/services 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
只想看最终结果
[root@linux ~]# awk '/^$/{i=i+1}END{print i}' /etc/services 
17

——6.7.2 统计/etc/passwd文件中有多少个虚拟用户

统计文件中所有以nologin结尾的行,总计有多少
[root@linux ~]# awk '/nologin$/{i=i+1}END{print i}' /etc/passwd
18
[root@linux ~]# awk '/nologin$/{i++}END{print i}' /etc/passwd
18

——6.7.3 直接完成求和运算

[root@linux ~]# seq 10
1
2
3
4
5
6
7
8
9
10
[root@linux ~]# seq 10|awk '{i=i+$1;print i}'
1
3
6
10
15
21
28
36
45
55
[root@linux ~]# seq 10|awk '{i=i+$1}END{print i}'
55
[root@linux ~]# seq 10|awk '{i+=$1}END{print i}'
55 

——6.7.3 利用awk取出文件权限数值信息

[root@linux ~]# stat /etc/hosts
File: ‘/etc/hosts’
Size: 158 Blocks: 8 IO Block: 4096 regular file
Device: 803h/2051d Inode: 33586486 Links: 2
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2022-03-24 21:10:19.857999552 +0800
Modify: 2013-06-07 22:31:32.000000000 +0800
Change: 2022-03-13 19:57:03.919334234 +0800
Birth: -
[root@linux ~]# stat /etc/hosts|awk -F '[(/]' 'NR==4{print $2}'
0644
[root@linux ~]# stat /etc/hosts|awk -vFS="[(/]" 'NR==4{print $2}'
0644

—6.8 根据secure文件, 如果统计出哪个IP地址失败次数最多

显示失败的IP地址 显示失败了多少次
按顺序显示前10名
(awk 数组)

7. grep命令汇总

grep(*) 三剑客命令 擅长过滤信息
grep -i 忽略大小写
grep -c 统计行数
grep -A 数值 显示过滤信息后几行信息
grep -B 数值 显示过滤信息前几行信息
grep -C 数值 显示过滤信息上下几行内容
grep -v 对过滤内容进行排除,显示其他的信息
grep -n 显示过滤出来数据内容的行号信息
grep -o 显示过滤的过程(只显示过滤的信息,默认会将一行信息都进行显示)
grep -E/egrep 可以识别扩展正则符号信息
grep -r 可以递归查找目录下面每一个文件的数据内容
grep -l 可以查找目录下面每一个文件的数据内容, 无法进入都目录中
赞(1)

评论 抢沙发

评论前必须登录!

 

LNMP社群 不仅仅是技术

关于我们网站地图