Linux学习65 实战使用awk高级功能统计网络请求连接状态
一、控制语句(接上集)
1、if-else
a、语法:if(condition) statement [else statement]
b、示例
(1)、显示系统上的普通用户(uid>1000)
[root@www ~]# awk -F: '{if($3>=1000)print $1,$3}' /etc/passwd testuser 5000 centos 5002 gentoo 5003 ...
(2)、1000以下显示系统用户,1000以上显示普通用户
[root@www ~]# awk -F: '{if($3>=100) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd root or Sysuser: root root or Sysuser: bin root or Sysuser: daemon ...
(3)、对awk取得的整行或某个字段做条件判断
[root@www ~]# awk -F: '{if($NF=="/bin/bash"){print $1}}' /etc/passwd root centos ...
(4)、如果某一行的字段数大于5个则显示否则则不显示
[root@www ~]# awk '{if(NF>5) print $0}' /etc/fstab # Created by anaconda on Tue Jun 4 22:30:32 2019 # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info /dev/mapper/centos-root / xfs defaults 0 0 UUID=fd514a18-84be-4460-8130-706b3ec88673 /boot xfs defaults 0 0 /dev/mapper/centos-swap swap swap defaults 0 0
(5)、显示系统上使用率大于80%的磁盘
[root@www ~]# df -hT|awk -F '%' '/^\/dev/{print $1}'|awk '{if($NF>=20) print $1}' /dev/mapper/centos-root
2、while循环
a、语法:while(condition) statement
(1)、条件“真”,进入循环;条件“假”,退出循环
b、使用场景:对一行内的多个字段逐一类似处理时使用,对数组中的各元素逐一处理时使用
c、示例
(1)、显示/etc/grub2.cfg相应过滤出来的行的字段的字符数
[root@www ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i);i++}}' /etc/grub2.cfg linux16 7 /vmlinuz-3.10.0-693.el7.x86_64 30 root=/dev/mapper/centos-root 28 ro 2 rd.lvm.lv=centos/root 21 rd.lvm.lv=centos/swap 21 rhgb 4 quiet 5 LANG=en_US.UTF-8 16 linux16 7 /vmlinuz-0-rescue-8d1d5981d45d4471a3a9f89d3611c71c 50 root=/dev/mapper/centos-root 28 ro 2 rd.lvm.lv=centos/root 21 rd.lvm.lv=centos/swap 21 rhgb 4 quiet 5
注意,定义恒定的变量时需要在BEGIN中进行定义,定义i这种会变化的变量时需要在'pogram'中定义。
(2)、只显示/etc/grub2.cfg文件中字符数大于等于七的字段
[root@www ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) print $i,length($i);i++}}' /etc/grub2.cfg linux16 7 /vmlinuz-3.10.0-693.el7.x86_64 30 root=/dev/mapper/centos-root 28 rd.lvm.lv=centos/root 21 rd.lvm.lv=centos/swap 21 LANG=en_US.UTF-8 16 linux16 7 /vmlinuz-0-rescue-8d1d5981d45d4471a3a9f89d3611c71c 50 root=/dev/mapper/centos-root 28 rd.lvm.lv=centos/root 21 rd.lvm.lv=centos/swap 21
3、do-while循环
a、语法:do statement while(condition)
意义:至少执行一次循环体
4、for循环
a、语法:for(expr1;expr2;expr3) statement
(1)、for(variable assignment;condition;iteration process) {for-body}
b、示例
(1)、显示/etc/grub2.cfg相应过滤出来的行的字段的字符数
[root@www ~]# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg linux16 7 /vmlinuz-3.10.0-693.el7.x86_64 30 root=/dev/mapper/centos-root 28 ro 2 rd.lvm.lv=centos/root 21 rd.lvm.lv=centos/swap 21 rhgb 4 quiet 5 LANG=en_US.UTF-8 16 linux16 7 /vmlinuz-0-rescue-8d1d5981d45d4471a3a9f89d3611c71c 50 root=/dev/mapper/centos-root 28 ro 2 rd.lvm.lv=centos/root 21 rd.lvm.lv=centos/swap 21 rhgb 4 quiet 5
(2)、显示字符数大于或等于7的字段
c、特殊用法:能够遍历数组中的元素
(1)、语法:for(var in array) {for-body}
5、switch语句(相当于case语句,多分支的if语句)
a、语法:switch(expression) {case VALUE1 or /REGEXP/:statement;case VALUE2 or /REGEXP2/:statement;...; default:statement}
6、break和continue
a、break [n] :跳出n层循环
b、continue:结束本轮循环执行下一轮循环
7、next:像continue一样,不过他是控制awk的内生循环的,即提前结束本行循环直接开始下一行。
a、示例,判断用户ID号是否为偶数
[root@www script]# awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd root 0 daemon 2 lp 4
...
8、array:awk中的数组
a、其一般都是关联数组:array[index-expression]
(1)、index-expression
1)、可以使用任意字符串,字符串要使用双引号
weekdays["mon"]="Monday"
[root@www script]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}' Monday
2)、如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”,如果写成array[index]++其会首先被赋值为1,如果再循环其会依次增加
[root@www script]# awk 'BEGIN{weekdays["mon"];print weekdays["mon"]}' [root@www script]# awk 'BEGIN{weekdays["mon"]++;print weekdays["mon"]}' 1
(2)、若要判断数组中是否存在某元素,要使用"index in array"格式进行
b、要遍历数组中的每个元素,要使用for循环
(1)、语法 for(var in array) {for-body}
[root@www script]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print weekdays[i]}}' Tuesday Monday
(2)、注意:var会遍历array的每个索引
c、常见用法示例
(1)、统计netstat -ant中tcp各状态出现的次数
[root@www script]# netstat -ant|awk '/^tcp\>/{print}' tcp 0 0 0.0.0.0:22222 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN tcp 0 52 192.168.10.13:22222 192.168.10.1:14138 ESTABLISHED [root@www script]# netstat -ant|awk '/^tcp\>/{state[$NF]++}END{for(i in state){print i,state[i]}}' LISTEN 3 ESTABLISHED 1
相当于我们是对最后这个字段进行统计,state[$NF]++他的意思每获取一行我们就试图把这一行的最后一个字段当做索引下标来对这个对应的数组元素进行自增操作,因此读第一行的时候数组state的第一个元素state["LISTEN"]就变成1了,读第二行的时候state["LISTEN"]就自增变成2了
(2)、现在我们启动我们的http服务然后统计访问过的ip地址
(3)、统计/etc/fstab文件中每个文件系统类型出现的次数
(4)、统计指定文件中每个单词出现的次数
9、函数
a、内置函数
(1)、数值处理:
rand():返回0和1之间的一个随机数。我们每一个awk进程取得到随机数每次都是一样的
[root@www script]# awk 'BEGIN{print rand()}' 0.237788 [root@www script]# awk 'BEGIN{print rand()}' 0.237788
(2)、字符串处理
length([s]):指定返回指定字符串的长度
sub(r,s,[t]):以r表示的模式来查找t所表示的字符串中的匹配的内容,并将其第一次出现替换为s所表示的内容
gsub(r,s,[t]):以r表示的模式来查找t所表示的字符串中的匹配的内容,并将其所有出现均替换为s所表示的内容
split(s,a,[r]):以r为分隔符切割字符s,并将其切割后的结果保存至a所表示的数组中
b、自定义函数
《sed和awk》