Linux三剑客


Linux三剑客

grep

-n :打印行号
-A :after 打印过滤内容的后N行
-B :before 打印过滤内容的前N行
-C :center 打印过滤内容的前后N行
-E :支持正则表达式
-v :取反
-o :只打印匹配到的内容
-w :精确匹配
-p :支持perk正则
-i :忽略大小写
-r :递归检索文件中的内容
-R :递归检索文件中的内容,包括软链接文件
-l :只显示文件名
-h :只显示文件内容
-f :对比文件内容,内容少的文件在前面,内容多的在后面,取反可以看到不同的文件内容
-C :统计行数,类似于  wc -l
-G :支持基础正则
-m :显示前N行 head -n

sed

在sed中,我们核心内容,主要分为四个部分:

  • 进阶内容 : 模式空间与保持空间

sed命令执行流程

执行 sed -n  '3p' 1.txt 命令后,sed都做了啥?
1.sed先是按行读取内容
2.没读取一行内容,都会进行一次判断,是不是你要的行
3.如果不是,则判断是不是加了-n选项
4.如果加了-n,就会读取下一行
5.如果没加-n,就会将所有内容输出到命令行(默认输出)
6.如果是,你想要的那一行,则判断执行的后续动作
7.动作处理完成后,输出指定的内容
8.几遍是读取完了,内容也输出了,sed也会继续往后读,直到文件最后一行

sed – 查

-n	# 取消默认输出
-r  #  支持扩展正则

# 动作
p	# print打印
d	# delete删除
c 	# 替换
a	# append追加
i	# insert插入

实例

# sed取消默认输出
[root@m01 ~]# sed -n '3p' 1.txt 
3.qqq

# sed显示多行内容并取消默认输出
[root@m01 ~]# sed -n '1,3p' 1.txt 
1.zls
2.cls
3.qqq

# sed模糊查询
[root@m01 ~]# sed -n '/zls/p' 1.txt 
1.zls
[root@m01 ~]# sed -n '/zls/,/qqq/ p' 1.txt 
1.zls
2.cls
3.qqq

# sed实现 grep -A 
[root@m01 ~]# sed -n '/zls/,+2p' 1.txt 
1.zls
2.cls
3.qqq

# sed 指定步长读取一行
[root@m01 ~]# sed -n '1~2p' 1.txt 
1.zls
3.qqq
5.zzz

sed – 删

d:delete

# 删除指定的行数,不修改原文件
[root@m01 ~]# sed '2d' 1.txt 
1.zls
3.qqq
4.aaa
5.zzz

# 删除最后一行
[root@m01 ~]# sed '$d' 1.txt
1.zls
2.cls
3.qqq
4.aaa

# 包含zls到aaa的行都删掉
[root@m01 ~]# sed  '/zls/,/aaa/d' 1.txt
5.zzz

sed – 增

c :replace 替换整行内容
[root@m01 ~]# sed '1c9.haksdk' 1.txt 
9.haksdk
2.cls
3.qqq
4.aaa
5.zzz

a :append 追加
[root@m01 ~]# sed '1a9.haksdk' 1.txt 
1.zls
9.haksdk
2.cls
3.qqq
4.aaa
5.zzz

i : insert 插入
[root@m01 ~]# sed '1i9.haksdk' 1.txt 
9.haksdk
1.zls
2.cls
3.qqq
4.aaa
5.zzz

sed – 改

s : substitute	替换
g : global	全局

s###g
s@@@g
s啥都行g

#基础用法
[root@m01 ~]# sed 's#zls#ZLS#g' 1.txt
1.ZLS
2.cls
3.qqq
4.aaa
5.zzz

# 使用正则
[root@m01 ~]# sed 's#[0-9]#666#g' 1.txt
666.zls
666.cls
666.qqq
666.aaa
666.zzz

# 后向引用
[root@m01 ~]# ifconfig  eth1|sed -nr 's#^.*inet (.*) net.*#/1#gp'
172.16.1.61 

sed的模式空间

将文件中的,所有换行符,替换成空格符
[root@m01 ~]# sed 'N;N;N;N;s#/n# #g' 1.txt

# 循环
[root@m01 ~]# sed ':label;N;s#/n# #g;t label' 1.txt 
1.zls 2.cls 3.qqq 4.aaa 5.zzz

1659082144303

awk执行流程

三个阶段

# 读取文件之前
	- BEGNO{}
	- 1.读取文件时,也是一行一行的读
	- 2.如果写了BEGN{}则先在BEGIN{}中执行
# 读取文件时
	- {}
	- 1.awk在读取文件时,也是一行一行的读
	- 2.读取一行之后,判断是否满足条件,如果是,则执行{对应动作}
	- 3.如果不满足条件,awk继续读取下一行,知道满足条件或者到文件的最后一行
# 读取文件之后
	- END{}
	- 1.所有文件读取完成之后,走END{}中的指令

awk的行与列

行 :记录 record
列 :字段 field

# 范围取行
[root@m01 ~]# awk 'NR>=1 && NR<=3' 1.txt 
1 Zeng Laoshi       133411023        :110:100:75
2 Deng Ziqi            44002231        :250:10:88
3 Zhang Xinyu      877623568      :120:300:200

# 包含Z和D的行
[root@m01 ~]# awk '/Z|D/' 1.txt 
1 Zeng Laoshi       133411023        :110:100:75
2 Deng Ziqi            44002231        :250:10:88
3 Zhang Xinyu      877623568      :120:300:200
5 Di Lireba             253097001      :220:100:200
8 Zhang Yuqi         376788757       :500:290:33
9 Wen Zhang         259872003      :100:200:300

# 取第三行到最后一行
[root@m01 ~]# awk 'NR>=3' 1.txt 
3 Zhang Xinyu      877623568      :120:300:200
4 Gu Linazha         11029987         :120:30:79
5 Di Lireba             253097001      :220:100:200
6 Jiang Shuying    535432779       :309:10:2
7 Ju Jingyi             68005178         :130:280:385
8 Zhang Yuqi         376788757       :500:290:33
9 Wen Zhang         259872003      :100:200:300

# 前三行
[root@m01 ~]# awk 'NR<=3' 1.txt 
1 Zeng Laoshi       133411023        :110:100:75
2 Deng Ziqi            44002231        :250:10:88
3 Zhang Xinyu      877623568      :120:300:200

# Zeng到Zhang的行
[root@m01 ~]# awk '/Zeng/,/Zhang/' 1.txt 
1 Zeng Laoshi       133411023        :110:100:75
2 Deng Ziqi            44002231        :250:10:88
3 Zhang Xinyu      877623568      :120:300:200

# awk的控制结束标记
[root@m01 ~]# awk -vRS=: 'NR==1' 1.txt 
1 Zeng Laoshi       133411023 

awk取行取列

# 取出top中的运行时间
[root@m01 ~]# top -n1 |awk 'NR==1{print $5}'
1
# 取出网卡配置文件的IP地址
[root@m01 ~]# awk -F= '/IPADDR/{print $2}' /etc/sysconfig/network-scripts/ifcfg-eth0 
10.0.0.61

# 找出姓氏是张的人,他们第二次捐款数额及姓名
[root@m01 ~]# cat 1.txt 
1 Zeng Laoshi       133411023        :110:100:75
2 Deng Ziqi            44002231        :250:10:88
3 Zhang Xinyu      877623568      :120:300:200
4 Gu Linazha         11029987         :120:30:79
5 Di Lireba             253097001      :220:100:200
6 Jiang Shuying    535432779       :309:10:2
7 Ju Jingyi             68005178         :130:280:385
8 Zhang Yuqi         376788757       :500:290:33
9 Wen Zhang         259872003      :100:200:300

[root@m01 ~]# awk -F '[ :]' 'BEGIN{print "性","名","捐款数额"}$2~/Zhang/{print $2,$3,$6}' 1.txt 
性 名 捐款数额
Zhang Xinyu 
Zhang Yuqi 

[root@m01 ~]# awk -F '[ :]' 'BEGIN{print "性","名","捐款数额"}$2~/Zhang/ && $3~/X/{print $2,$3,$6}' 1.txt 
性 名 捐款数额
Zhang Xinyu

# 每个捐款值都已$开头
[root@m01 ~]# awk '{gsub(/:/,"$");print $0}' 1.txt 
1 Zeng Laoshi       133411023        $110$100$75
2 Deng Ziqi            44002231        $250$10$88
3 Zhang Xinyu      877623568      $120$300$200
4 Gu Linazha         11029987         $120$30$79
5 Di Lireba             253097001      $220$100$200
6 Jiang Shuying    535432779       $309$10$2
7 Ju Jingyi             68005178         $130$280$385
8 Zhang Yuqi         376788757       $500$290$33
9 Wen Zhang         259872003      $100$200$300

# 找出 ifconfig中范围是1~255的数字
[root@m01 ~]# ifconfig |awk -vRS='[^0-9]+' '$0>=1 && $0<=255'
172
17
1
255
255
172
17
255
255

总结

column -t # 将输出对其

# 内置变量
NR	# 取行
RS	# 控制结束标记  分割符
FS	# 列的分割符
NF	# 每一行有多少列
OFS # 输出指定 
gsub(/替换内容/,"新内容",第几列)

awk模式与动作

awk -F: 'NR==1{print $1,$3}' /etc/password

上面这条命令我们可以看到,'NR==1{print $1,$3}'可以理解为 '模式{动作}' == '条件{指令}' 

awk中的模式

正则表达式

# 正则表达式写法
'/正则表达式/flag'
'$1~/正则表达式/flag'
'$1!~/正则表达式/flag'

只不过在awk中很少使用flag

比较表达式

NR==1
NR>=10
NR<=100
NR>=1 && NR<=10
$1>=100

范围模式

# 精确匹配行号:从第10行到第20行
NR==10,NR==20

# 精确匹配字符串:从该字符创的行到另一个字符串所在的行
'/root/,/zls/'
'/从哪个字符串所在行/,/到那个字符串所在行/'	# 中间的行都包含进去

# 模糊匹配字符串:从含有该字符串所在行到另一字符串所在行
'$1~/oo/,$1~/zl/'

特殊模式

BEGIN
END

awk中的动作

在awk中,我们最常用的动作就是print
当然我们还有别的动作可以使用:
	- print打印
	- gsub替换
	- 变量赋值
	- 统一计算
	
如果要使用BEGIN模式,那么一定要成双成对的出现
那么我们要知道,BEGIN{}中,大括号里面的内容,会在读取文件内容之前执行

主要应用场景
- 1.计算
- 2.awk功能测试
- 3.输出表格的表头

END模式

一般来说,END{}要比BEGIN{}可有可无,计算其实可以放在读取文件的时候,也可以执行END{}中,大括号里面的内容,会在wak读取完文件的最后一行,进行处理

作用:一般我们使用END{}来显示对日志内容分析后的一个结果,当然还有其他功能,比如文件读取完了,可以显示一些尾部信息

# 1.统计/etc/service文件中一共有多少行	,不要过程,只要结果
[root@m01 ~]# awk 'END{print NR}' /etc/services 
11176

[root@m01 ~]# awk '{i++}END{print i}' /etc/services 
11176
# 流氓写法
[root@m01 ~]# sed -n '$=' /etc/services 
11176
[root@m01 ~]# grep -c '.*' /etc/services 
11176
[root@m01 ~]# wc -l /etc/services 
11176 /etc/services

# 2.统计/etc/service中的空行数量
[root@m01 ~]# awk '/^$/{i++}END{print i}' /etc/services 
17

# 3.统计出下列文件中所有人的年龄和
[root@m01 ~]# cat 1.txt 
姓名      年龄
曾老湿    23
苍颈空    18
西冶详    9

[root@m01 ~]# awk 'NR!=1{n+=$2}END{print n}' 1.txt 
140

# 4.统计nginx日志中,状态码时200的次数以及状态码200时占用的流量
[root@m01 ~]# zcat blog.driverzeng.com_access.log-20220623.gz |awk '$10~/^[45]/{i++;n+=$11}END{print i,n}'
580 519243

# 5.统计nginx日志中状态码时4xx和5xx的次数以及总流量
zcat blog.driverzeng.com_access.log-20220623.gz |awk '
$10~/200/{
        i++;b+=$11
}
$10~/^3/{
        o++;p+=$11
}
$10~/^[4-5]/{
        u++;y+=$11
}
END{
        print i,b;
        print o,p;
        print u,y;
}'

# 6.综合应用:分别统计每种状态码的次数和每个状态码的总流量
zcat blog.driverzeng.com_access.log-20220623.gz |awk '
BEGIN{
        print "状态码","总流量"
}
$10~/200/{
        i1++;n1+=$11
}
$10~/^3/{
        i2++;n2+=$11
}
$10~/^4/{
        i3++;n3+=$11
}
$10~/^5/{
        i4++;n4+=$11
}
END{
        print "200的次数"i1,"200的流量:"n1
        print "3xxx的次数"i2,"3xx的流量:"n2
        print "4xx次数:"i3,"4xxx的流量:"n3
        print "5xx的次数:"i4,"5xx的流量:"n4
}'|column -t

awk数组

在awk中的属组数据类型,是非常好用的的一个类型,不像是shell,当然shell中数组也有它自己的优点。
awk中的数组,专门用来统计不同的分类。
** 例如:** 1.nginx日志中每个IP出现的次数 2.nginx日志中每种状态码出现的次数 3.nginx日志中每个URI的访问次
数

awk数组赋值

[root@m01 ~]# awk 'BEGIN{array[0]="zls";array[1]="cls"}'

awk数组取值

[root@m01 ~]# awk 'BEGIN{array[0]="zls";array[1]="cls";print array[0],array[1]}'
zls cls

awk循环数组

for(){
动作
}

# 统计nginx日志中的每一个IP地址访问的次数
[root@m01 ~]# zcat blog.driverzeng.com_access.log-20220623.gz |awk '{array[$1]++}END{for(ip in array){print ip,array[ip]}}'

# 1.取出下列域名并根据域名,进行统计排序处理
[root@m01 ~]# awk -F/ '{domain[$3]++}END{for(name in domain){print name,domain[name]}}' 1.txt 
blog.driverzeng.com 3
post.driverzeng.com 2
mp3.driverzeng.com 1

# 2.统计nginx日志中,每个IP访问使用的流量总和
[root@m01 ~]# zcat blog.driverzeng.com_access.log-20220623.gz |awk '{ip[$1]++;ll[$1]+=$11}END{for(i in ip){print i,ip[i],ll[i]}}'

qwk的判断

# shell
if [ 条件 ];then
	动作
fi

# awk
if (条件){
	动作
}else{
	动作
}

if (条件){
	动作
}else if(条件){
	动作
}else{
	动作
}
# 判断磁盘使用率大于70%,大于显示磁盘空间不足,不打于显示正常
[root@m01 ~]# df -h|awk -F '[ %]+' 'NR==2{if($5>70){print "磁盘空间 不足"}else{print "磁盘空间充足,当前使用率:"$5"%"}}'
磁盘空间充足,当前使用率:15%

作业

#2.企业面试题:统计每个学生的总成绩和平均成绩
stu01 70 80 90 100 90 80
stu02 89 78 98 67 97 90
stu03 56 12 33 44 55 66 77
stu04 89 78 77 99 100 30
stu05 98 97 96 95 94 93
stu06 100 20 20 20 20 20

[root@m01 ~]# awk '{sum=0;for(i=2;i<=NF;i++){sum+=$i};print sum,sum/(NF-1)}' 1.txt
510 85
519 86.5
343 49
473 78.8333
573 95.5
200 33.3333

原创文章,作者:306829225,如若转载,请注明出处:https://blog.ytso.com/278325.html

(0)
上一篇 2022年8月2日
下一篇 2022年8月2日

相关推荐

发表回复

登录后才能评论