1. awk 擅长功能
awk 擅长对列进行操作/进行数据信息的统计(数组)
awk 基本使用(高级使用-shell)
2. awk 概念介绍说明
2.1 作用特点
- 排除信息
- 查询信息
- 统计信息
- 替换信息
2.2 awk 语法格式
awk [参数] ‘模式-动作’ 文件
3. awk 原理说明
image-20210822212732717.png4. awk 实战操作
4.1 准备测试环境
[yunxuan@yunxuanedu ~]$ cat awk_test.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
4.2 查询
4.2.1 按照行号查询
# 取第2行
awk 'NR==2' awk_test.txt
[yunxuan@yunxuanedu ~]$ awk 'NR==2' awk_test.txt
Zhang xiaoyu 390320151 :155:90:201
# 取第2-4行
awk 'NR==2,NR==4' awk_test.txt
[yunxuan@yunxuanedu ~]$ awk 'NR==2,NR==4' awk_test.txt
Zhang xiaoyu 390320151 :155:90:201
Meng Feixue 80042789 :250:60:50
Wu waiwai 70271111 :250:80:75
# 取第2行 和 第4行
awk 'NR==2;NR==4' awk_test.txt
[yunxuan@yunxuanedu ~]$ awk 'NR==2;NR==4' awk_test.txt
Zhang xiaoyu 390320151 :155:90:201
Wu waiwai 70271111 :250:80:75
4.2.2 按照字符查询
# 取 'xiaoyu' 所在行
awk '/xiaoyu/' awk_test.txt
[yunxuan@yunxuanedu ~]$ awk '/xiaoyu/' awk_test.txt
Zhang xiaoyu 390320151 :155:90:201
# 取 'xiaoyu' 至 'Bingbing' 所在行
awk '/xiaoyu/,/Bingbing/' awk_test.txt
[yunxuan@yunxuanedu ~]$ awk '/xiaoyu/,/Bingbing/' awk_test.txt
Zhang xiaoyu 390320151 :155:90:201
Meng Feixue 80042789 :250:60:50
Wu waiwai 70271111 :250:80:75
Liu Bingbing 41117483 :250:100:175
# 取 'xiaoyu' 和 'Bingbing' 所在行
awk '/xiaoyu/;/Bingbing/' awk_test.txt
[yunxuan@yunxuanedu ~]$ awk '/xiaoyu/;/Bingbing/' awk_test.txt
Zhang xiaoyu 390320151 :155:90:201
Liu Bingbing 41117483 :250:100:175
4.2.3 特殊查询
# 显示 'xiaoyu' 所在行的 姓氏 和 ID 信息
awk '/xiaoyu/{print $1,$3}' awk_test.txt
[yunxuan@yunxuanedu ~]$ awk '/xiaoyu/{print $1,$3}' awk_test.txt
Zhang 390320151
# 找出姓氏是 zhang 的人,显示他的第二次捐款金额及它的名字
# [ :]+ 表示以':'和' '来分割,'+'表示
awk -F "[ :]+" '/Zhang/{print $2,$(NF-1)}' awk_test.txt
[yunxuan@yunxuanedu ~]$ awk -F "[ :]+" '/Zhang/{print $2,$(NF-1)}' awk_test.txt
Dandan 100
xiaoyu 90
# 显示所有以41开头的ID号码的人的全名和ID号码
awk '$3~/^41/{print $1,$2,$3}' awk_test.txt
[yunxuan@yunxuanedu ~]$ awk '$3~/^41/{print $1,$2,$3}' awk_test.txt
Zhang Dandan 41117397
Liu Bingbing 41117483
# 显示所有ID号码最后一位数字是1或5的人的全名
#方法一
[yunxuan@yunxuanedu ~]$ awk '$3~/[15]$/{print $1,$2,$3}' awk_test.txt
Zhang xiaoyu 390320151
Wu waiwai 70271111
Wang xiaoai 3515064655
Li youjiu 918391635
Lao Nanhai 918391635
# 方法二
[yunxuan@yunxuanedu ~]$ awk '$3~/1$|5$/{print $1,$2,$3}' awk_test.txt |column -t
Zhang xiaoyu 390320151
Wu waiwai 70271111
Wang xiaoai 3515064655
Li youjiu 918391635
Lao Nanhai 918391635
# 方法三
[yunxuan@yunxuanedu ~]$ awk '$3~/(1|5)$/{print $1,$2,$3}' awk_test.txt | column -t
Zhang xiaoyu 390320151
Wu waiwai 70271111
Wang xiaoai 3515064655
Li youjiu 918391635
Lao Nanhai 918391635
# 显示 xiaoyu 的捐款,每个捐款数值前面都以 $ 开头,如$110$220$330
[yunxuan@yunxuanedu ~]$ awk -F "[ :]+" '/xiaoyu/{print $1,$2,"$"$(NF-2)"$"$(NF-1)"$"$NF}' awk_test.txt
Zhang xiaoyu $155$90$201
# 扩展
# gsub(/需要替换的信息/,"修改成什么信息",将那列信息进行修改)
[yunxuan@yunxuanedu ~]$ awk '$2~/xiaoyu/{gsub(/:/,"$",$NF);print $NF}' awk_test.txt
$155$90$201
image-20210822213945075.png
#【注意】 区分 $NF-1 和 $(NF-1) 的区别
[yunxuan@yunxuanedu ~]$ awk -F "[ :]+" '/Zhang/{print $2,$NF-1}' awk_test.txt
Dandan 174
xiaoyu 200
[yunxuan@yunxuanedu ~]$ awk -F "[ :]+" '/Zhang/{print $2,$NF}' awk_test.txt
Dandan 175
xiaoyu 201
4.2.4 排除空行和注释行
grep -Ev "^#|$" 文件信息
sed -rn '/^#|^$/!p' 文件信息
sed -r '/^#|^$/d' 文件信息
# 方法一(删除)
awk '!/^#|^$/' awk_test.txt
[yunxuan@yunxuanedu ~]$ cat awk_test.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
[yunxuan@yunxuanedu ~]$ awk '/^#|^$/' awk_test.txt
#Zhang xiaoyu 390320151 :155:90:201
[yunxuan@yunxuanedu ~]$ awk '!/^#|^$/' awk_test.txt
Zhang Dandan 41117397 :250:100:175
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
# 方法二
awk '$0!~/^#|^$/' awk_test.txt
[yunxuan@yunxuanedu ~]$ awk '$0~/^$|^#/' awk_test.txt
#Zhang xiaoyu 390320151 :155:90:201
[yunxuan@yunxuanedu ~]$ awk '$0!~/^$|^#/' awk_test.txt
Zhang Dandan 41117397 :250:100:175
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
4.2.5 取IP
[yunxuan@yunxuanedu ~]$ ip address show eth0|awk -F "[ /]+" 'NR==3{print $3}'
172.29.94.63
5. awk命令中$符号用法
$1 $2 $3 取第几列信息
$NF 取最后一列
$(NF-n) 取倒数第n+1列
$0 去所有列的信息
6. awk高级功能说明
6.1 概述
-
对日志信息进行统计(计数)
-
对日志信息数值进行求和 客户端-下载 服务端-上传 消耗网络流量
-
(数组) 进行排序分析
-
可以进行脚本编写(循环语句 判断语句)
6.2 awk模式概念说明:匹配的条件信息
6.2.1 普通模式
- 正则表达式作为模式
awk '/^yunxuan/{print $n}' awk_test.txt
- 比较表达式作为模式
awk 'NR>2' awk_test.txt
awk 'NR<2' awk_test.txt
- 范围模式
# 2-4 行
awk 'NR==2,NR==4' awk_test.txt
6.2.2 特殊模式
- BEGIN{} ,在
awk
执行命令之前 执行
# 案例,添加表头
[yunxuan@yunxuanedu ~]$ awk 'BEGIN{print "姓","名","ID","捐款详情"}{print $0}' awk_test.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
- 用于计算 案例
# 案例一
[yunxuan@yunxuanedu ~]$ awk 'BEGIN{print 10+3}'
13
[yunxuan@yunxuanedu ~]$ awk 'BEGIN{print 10-3}'
7
[yunxuan@yunxuanedu ~]$ awk 'BEGIN{print 10/3}'
3.33333
[yunxuan@yunxuanedu ~]$ awk 'BEGIN{print 10*3}'
30
[yunxuan@yunxuanedu ~]$ echo $((10-3))
7
[yunxuan@yunxuanedu ~]$ echo $((10+3))
13
[yunxuan@yunxuanedu ~]$ echo $((10/3))
3
[yunxuan@yunxuanedu ~]$ echo $((10*3))
30
- END{} ,在
awk
执行命令之后 执行
# 案例
[yunxuan@yunxuanedu ~]$ awk 'BEGIN{print "姓","名","ID","捐款详情"}{print $0}END{print "执行完成"}' awk_test.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
执行完成
- awk 内置变量
FS -- 字段分隔符变量
NR -- 表示行号信息
NF -- 表示每行有多少列
[yunxuan@yunxuanedu ~]$ awk -F ":" '{print $2}' awk_test.txt
250
155
250
250
250
50
250
175
250
[yunxuan@yunxuanedu ~]$ awk 'BEGIN{FS=":"}{print $2}' awk_test.txt
250
155
250
250
250
50
250
175
250
[yunxuan@yunxuanedu ~]$ awk -vFS=":" '{print $2}' awk_test.txt
250
155
250
250
250
50
250
175
250
# awk 设置变量并调用
[yunxuan@yunxuanedu ~]$ awk -va=1234 '{print a}' awk_test.txt
1234
1234
1234
1234
1234
1234
1234
1234
1234
6.3 高级功能案例演示
6.3.1 统计 /etc/services
文件中空行的数量
[yunxuan@yunxuanedu ~]$ 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
[yunxuan@yunxuanedu ~]$ awk '/^$/{i=i+1}END{print i}' /etc/services
17
# 其他方法
[yunxuan@yunxuanedu ~]$ awk '/^$/' /etc/services|wc -l
17
[yunxuan@yunxuanedu ~]$ grep -c "^$" /etc/services
17
6.3.2 统计 /etc/services
文件中注释行的数量
awk '/^#/{i++}END{print i}' /etc/services
[yunxuan@yunxuanedu ~]$ awk '/^#/{i++}END{print i}' /etc/services
102
6.3.3 统计系统中虚拟用户的数量
[yunxuan@yunxuanedu ~]$ awk '$NF!~/bash$/{i++}END{print i}' /etc/passwd
23
6.3.4 统计系统中普通用户的数量
[yunxuan@yunxuanedu ~]$ awk '$NF~/bash$/{i++}END{print i-1}' /etc/passwd
1
6.4 求和运算
sum=sum+$n
[yunxuan@yunxuanedu ~]$ seq 10|awk '{sum=sum+$1;print sum}'
1
3
6
10
15
21
28
36
45
55
[yunxuan@yunxuanedu ~]$ seq 10|awk '{sum=sum+$1}END{print sum}'
55
- 求出测试文件中,所有人第一次捐款的总额和第三次捐款总额
显示表头
第一次总额 第三次总额
[yunxuan@yunxuanedu ~]$ awk -vFS="[ :]+" 'BEGIN{print "第一次捐款总额","第三次捐款总额"}{sum1=sum1+$(NF-2)}{sum3=sum3+$NF}END{print sum1,sum3}' awk_test.txt|column -t
第一次捐款总额 第三次捐款总额
1880 1486
[yunxuan@yunxuanedu ~]$ awk -vFS="[ :]+" 'BEGIN{print "第一次捐款总额","第三次捐款总额"}{sum1=sum1+$(NF-2);sum3=sum3+$NF}END{print sum1,sum3}' awk_test.txt|column -t
第一次捐款总额 第三次捐款总额
1880 1486
网友评论