第1章 awk的用法
1.1 awk主要可以干什么
1.取列 取行 计算统计 查找 变量
2.统计
1.2 awk结构
awk -F "[ :]+" 'NR==2{print $4}'
awk 参数 '模式{动作}'
[root@wangyoukun ~]# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:0C:29:00:16:B4
inet addr:10.0.0.200 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe00:16b4/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:58949 errors:0 dropped:0 overruns:0 frame:0
TX packets:80971 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:11036576 (10.5 MiB) TX bytes:80575920 (76.8 MiB)
[root@wangyoukun ~]# ifconfig eth0|awk -F "[ :]+" 'NR==2{print $4}'
10.0.0.200
1.3 awk的执行过程
行 列
awk –F ":"=======> awk -vFS=":"
awk -F ":" '{print $1","$3}' passwd.txt
awk -vFS=":" '{print $1,$3}' passwd.txt
[root@wangyoukun ~]# cat passwd.txt |awk -vFS=":" '{print $1","$3}'
root,0
bin,1
daemon,2
adm,3
lp,4
sync,5
shutdown,6
halt,7
mail,8
awk -F: -vOFS=":" =====> awk –vFs=: -vOFS=":"
[root@wangyoukun ~]# cat passwd.txt|awk -F: -vOFS=":" '{print $NF,$2,$3,$4,$5,$6,$1}'
/bin/bash:x:0:0:root:/root:root
/sbin/nologin:x:1:1:bin:/bin:bin
/sbin/nologin:x:2:2:daemon:/sbin:daemon
/sbin/nologin:x:3:4:adm:/var/adm:adm
/sbin/nologin:x:4:7:lp:/var/spool/lpd:lp
/bin/sync:x:5:0:sync:/sbin:sync
/sbin/shutdown:x:6:0:shutdown:/sbin:shutdown
/sbin/halt:x:7:0:halt:/sbin:halt
/sbin/nologin:x:8:12:mail:/var/spool/mail:mail
[root@wangyoukun ~]# cat passwd.txt|awk -F: -vOFS=":" '{tmp=$1;$1=$NF;$NF=tmp;print}'
/bin/bash:x:0:0:root:/root:root ###条件tmp 是空杯,$1 是可乐,$NF 是雪碧
/sbin/nologin:x:1:1:bin:/bin:bin ###问题:如何调换可乐与雪碧的杯子?
/sbin/nologin:x:2:2:daemon:/sbin:daemon ###解答:有一个空杯,可以实现互换液体
/sbin/nologin:x:3:4:adm:/var/adm:adm ###过程:把可乐放进空杯,再将雪碧放进盛放可乐的空杯
/sbin/nologin:x:4:7:lp:/var/spool/lpd:lp ###子中,最后把盛放可乐的杯子放进盛放雪碧的杯子
/bin/sync:x:5:0:sync:/sbin:sync
/sbin/shutdown:x:6:0:shutdown:/sbin:shutdown
/sbin/halt:x:7:0:halt:/sbin:halt
/sbin/nologin:x:8:12:mail:/var/spool/mail:mail
1.4 通过awk找到你要的内容-模式
正则表达式作为模式
比较表达式作为模式 NR>10
范围模式
特殊模式BEGIN和END
1.4.1 正则表达式作为模式
#第3列 包含 数字3-5的行显示出来
[root@wangyoukun ~]# cat passwd.txt
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
[root@wangyoukun ~]# awk -F":" '$3~/[3-5]/' passwd.txt #第3列 匹配 数字3-5的行显示出来
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
#第5列 包含 字母的行显示出来
[root@oldboyedu45-lnb oldboy]# awk -F: '$5~/[a-z]/' passwd.txt
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
创建环境
cat >>/oldboy/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
姓氏是Zhang的人,显示他的第二次捐款金额及她的名字
[root@wangyoukun oldboy]# cat 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
[root@wangyoukun oldboy]# awk -F "[ :]+" '$1~/Zhang/{print $5,$1,$2}' reg.txt
100 Zhang Dandan ##姓氏是Zhang的人,显示他的第二次捐款金额及她的名字
90 Zhang Xiaoyu ##第二次捐款是$5
[root@oldboyedu45-lnb oldboy]# awk -F "[ :]+" '$1~/Zhang/{print $1,$2,$(NF-1)}' reg.txt
Zhang Dandan 100 ##姓氏是Zhang的人,显示他的第二次捐款金额及她的名字
Zhang Xiaoyu 90 ##第二次捐款是最后一列的前一列,记住括号要括起来
[root@oldboyedu45-lnb oldboy]# awk '$1~/Zhang/' reg.txt ##姓氏是Zhang的行
Zhang Dandan 41117397 :250:100:175
Zhang Xiaoyu 390320151 :155:90:201
awk 取第一行 NR==1 ==> NR==1{print $0} ==> NR==1{print }
[root@oldboyedu45-lnb oldboy]# awk 'NR==1' reg.txt
Zhang Dandan 41117397 :250:100:175
[root@oldboyedu45-lnb oldboy]# awk 'NR==1{print $0}' reg.txt
Zhang Dandan 41117397 :250:100:175
[root@oldboyedu45-lnb oldboy]# awk 'NR==1{print }' reg.txt
Zhang Dandan 41117397 :250:100:175
显示所有ID号码最后一位数字是1或5的人的全名
[root@oldboyedu45-lnb oldboy]# awk '$3~/[15]$/' reg.txt
Zhang Xiaoyu 390320151 :155:90:201 ##显示所有ID号码最后一位数字是1或5的人的行
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@oldboyedu45-lnb oldboy]# awk '$3~/[15]$/{print $1,$2}' reg.txt
Zhang Xiaoyu ##显示所有ID号码最后一位数字是1或5的人的全名
Wu Waiwai
Wang Xiaoai
Li Youjiu
Lao Nanhai
[root@wangyoukun oldboy]# awk '$2~/Xiaoyu/{gsub(/:/,"$",$NF);print}' reg.txt
Zhang Xiaoyu 390320151 $155$90$201 ##显示Xiaoyu的捐款.每个值时都有以$开头.如$520$200$135
1.5 awk 替换
gsub(//,"",$NF)
gsub(/你要找的内容/,"替换成什么",在哪里列里面进行替换)
[root@oldboyedu45-lnb oldboy]# awk '{gsub(/:/,"$",$NF)}' reg.txt
[root@oldboyedu45-lnb oldboy]# awk '{gsub(/:/,"$",$NF); print}' 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
显示所有人的全名,以姓,名的格式显示,如Meng,Feixue
[root@oldboyedu45-lnb oldboy]# awk -vOFS=, '{print $1,$2}' reg.txt
Zhang,Dandan
Zhang,Xiaoyu
Meng,Feixue
Wu,Waiwai
Liu,Bingbing
Wang,Xiaoai
Zi,Gege
Li,Youjiu
Lao,Nanhai
[root@wangyoukun oldboy]# awk '{print $1","$2}' reg.txt
Zhang,Dandan
Zhang,Xiaoyu
Meng,Feixue
Wu,Waiwai
Liu,Bingbing
Wang,Xiaoai
Zi,Gege
Li,Youjiu
Lao,Nanhai
101.226.61.184 - - [22/Nov/2015:11:02:00 +0800] "GET /mobile/theme/oldboy/common/images/arrow-down2.png HTTP/1.1" 200 24662 "http://m.oldboyedu.com.cn/mobile/theme/oldboy/home/index.html" "Mozilla/5.0 (Linux; U; Android 5.1.1; zh-cn; HUAWEI CRR-UL00 Build/HUAWEICRR-UL00) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.4 TBS/025478 Mobile Safari/533.1 MicroMessenger/6.3.7.51_rbb7fa12.660 NetType/3gnet Language/zh_CN"
1.5.1 特殊的模式BEGIN{} END{}
BEGIN{} 模块在awk读取文件之前就执行
[root@wangyoukun oldboy]# awk -vOFS=, 'BEGIN{print "wangyoukun"}{print $1,$2}END{print "oldboy"}' reg.txt
wangyoukun
Zhang,Dandan
Zhang,Xiaoyu
Meng,Feixue
Wu,Waiwai
Liu,Bingbing
Wang,Xiaoai
Zi,Gege
Li,Youjiu
Lao,Nanhai
oldboy
awk 'BEGIN{print "start"} {print}' reg.txt
[root@wangyoukun oldboy]# awk 'BEGIN{print "start"} {print }' reg.txt
start
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
1)测试
2) 定义或修改awk内置变量
-vOFS=: =====> 'BEGIN{OFS=:}'
END{}在awk读取完所有的文件的时候,再执行END模块,一般用来输出一个结果(累加,数组结果),
先计算,END{}显示最终结果
1.6 企业案例 :统计/etc/services文件里面的空行数量
#i=i+1 ===> i++ 计算总次数
[root@oldboyedu45-lnb oldboy]# awk '/^$/{i++}END{print i}' /etc/services
16 ##统计/etc/services文件里面的空行数量
[root@oldboyedu45-lnb oldboy]# awk '/^$/{i=i+1 }END{print i}' /etc/services
16
[root@wangyoukun oldboy]# seq 10|awk '{i=i+$1}END{print i}'
55 ##计算从1加到10的结果
[root@wangyoukun oldboy]# seq 1 10|awk '{print i=i+$1}END{print i}'
1
3
6
10
15
21
28
36
45
55
55
[root@wangyoukun oldboy]# seq 1 10|awk '{i=i+$1}END{print i}'
55
# 计算access.log中 一共使用了多少流量?
sum+=$10 ====> sum=sum+$10
[root@wangyoukun ~]# awk '{sum=sum+$10}END{print sum}' access.log
2478496663 ##计算access.log中 一共使用了多少流量?
[root@wangyoukun ~]# awk '{sum=sum+$10}END{print sum/1024^3}' access.log
2.30828 ##计算access.log中 一共使用了多少流量?没有加单位
[root@wangyoukun ~]# awk '{sum=sum+$10}END{print sum/1024^3"G"}' access.log
2.30828G ##计算access.log中 一共使用了多少流量?单位是G
1.7 小结 awk
1.BEGIN{} END{}√
2.awk统计-核心:先计算然后END{}显示结果
3.
i=i+1 === i++ 计算总次数
i=i+$xx === i+=$xxx 计算总和
[root@wangyoukun ~]# seq 10|awk '{i=i+1}END{print i}'
10
[root@wangyoukun ~]# seq 10|awk '{i=i+$1}END{print i}'
55
[root@wangyoukun ~]# awk '{print NR, $0}' passwd.txt ###显示行号
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
1.8 awk数组
处理以下文件内容,将域名取出并根据域名进行计数排序处理:(百度和sohu面试题)
http://www.etiantian.org/index.html
http://www.etiantian.org/1.html
http://post.etiantian.org/index.html
http://mp3.etiantian.org/index.html
http://www.etiantian.org/3.html
http://post.etiantian.org/2.html
分类统计 www post mp3 ......出现的次数
过程1 简单但是繁琐需要三步
[root@wangyoukun oldboy]# awk -F "[./]+" '$2~/www/{i=i+1}END{print i}' html.txt
3
[root@wangyoukun oldboy]# awk -F "[./]+" '$2~/post/{i=i+1}END{print i}' html.txt
2
[root@wangyoukun oldboy]# awk -F "[./]+" '$2~/mp3/{i=i+1}END{print i}' html.txt
1
过程2 繁琐
[root@oldboyedu45-lnb oldboy]# awk -F "[./]+" '$2~/www/{a++}$2~/post/{b++}$2~/mp3/{c++}END{print a,b,c}' url.txt ###这种情况只适合于小文件,种类较少的情况,不便于查看
3 2 1 ###不建议用这种方法,那么数组就产生了
过程3 精简了
[root@wangyoukun oldboy]# cat html.txt|awk -F "[./]+" '{h[$2]++}END{for(pol in h)print pol,h[pol]}'
www 3 ##分类统计 www post mp3 ......出现的次数
mp3 1
post 2 #####套用公式比较方便
数组的理解:
变量列表里的所有内容;
END 告诉并且给出结果
变量在变量列表里边;
打印变量和变量出现的次数
1.9 数组的诞生过程
[root@oldboyedu45-lnb oldboy]# awk 'BEGIN{h[110]="taotao";print h[110]}'
taotao
[root@oldboyedu45-lnb oldboy]# awk -F "[/.]+" '{h[$2]++;print "www",h["www"]}' url.txt
www 1
www 2
www 2
www 2
www 3
www 3
h[$2]++
[root@oldboyedu45-lnb oldboy]# awk -F "[/.]+" '{h[$2]++}END{print h["www"],h["mp3"],h["post"]}' url.txt
3 1 2
[root@oldboyedu45-lnb oldboy]# awk -F "[/.]+" '{h[$2]++}END{for(pol in h) print pol }' url.txt
www
mp3
post
[root@oldboyedu45-lnb oldboy]# awk -F "[/.]+" '{h[$2]++}END{for(pol in h) print pol,h[pol] }' url.txt
www 3
mp3 1
post 2
'{h[$2]++}END{for(pol in h) print pol h[pol] }'
变量 数组(变量列表) 元素名称,内容
房间号码
统计access.log中每个ip的访问次数
awk '{h[$1]++}END{for(pol in h) print pol,h[pol]}' access.log |sort -rnk2|head
[root@wangyoukun ~]# awk '{h[$1]++}END{for(pol in h) print pol,h[pol]}' access.log |head |sort -rnk2
101.226.125.119 569
180.154.137.177 516
101.226.125.118 437
180.158.118.17 347
101.226.125.115 284
14.152.68.38 162
140.206.89.150 130
101.226.125.116 127
117.12.191.55 106
110.75.248.79 1
1.10 awk 数组知识小结
1.10.1 数组活学活用
awk -F "[/.]+" '{h[$2]++}END{for(pol in h) print pol,h[pol] }' url.txt
拿好菜刀(分隔符),找到要统计的列,计算结果
1.10.2 计算总次数 i=i+1 === i++
awk '/^$/{i++}END{print i}' /etc/services
##统计/etc/services文件里面的空行数量
1.10.3 计算总和 i=i+$xx === i+=$xxx
awk '{sum=sum+$10}END{print sum}' access.log
seq 10|awk '{i=i+$1}END{print i}'
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步