一,awk的作用
1,用途
AWK是一种处理文本文件的语言,
是一个强大的文本分析工具
2,awk和sed的区别
awk适合按列(域)操作,
sed适合按行操作
awk适合对文件的读取分析,
sed适合对文件的编辑
说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest
对应的源码可以访问这里获取: https://github.com/liuhongdi/
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,查看awk命令所属的包
[root@blog ~]# whereis awk awk: /usr/bin/awk /usr/libexec/awk /usr/share/awk /usr/share/man/man1/awk.1.gz /usr/share/man/man1p/awk.1p.gz [root@blog ~]# rpm -qf /usr/bin/awk gawk-4.2.1-1.el8.x86_64
可以看到awk所属的包是gawk,
如果系统提示找不到awk命令时,
可以用dnf命令安装
[root@blog ~]# dnf install gawk
另外:我们使用的awk命令其实是gawk(gnu awk)
仍然叫awk其实是因为向unix上的awk命令兼容
awk命令其实是到gawk命令的一个符号链接
[root@blog ~]# ll /usr/bin/awk lrwxrwxrwx. 1 root root 4 May 11 2019 /usr/bin/awk -> gawk
三, 查看awk的版本和帮助
1,查看版本
[root@blog ~]# awk --version GNU Awk 4.2.1, API: 2.0 (GNU MPFR 3.1.6-p2, GNU MP 6.1.2) Copyright (C) 1989, 1991-2018 Free Software Foundation. ...
2,查看帮助
[root@blog ~]# awk --help
3,查看手册
[root@blog ~]# man awk
四,awk应用例子之一:查看磁盘占用高的分区
1, 得到使用20%以上的分区
先看df的结果:
[liuhongdi@centos8 ~]$ df -h 文件系统 容量 已用 可用 已用% 挂载点 devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 1.9G 0 1.9G 0% /dev/shm tmpfs 1.9G 10M 1.9G 1% /run tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup /dev/mapper/cl-root 50G 9.1G 41G 19% / /dev/mapper/cl-home 26G 1.2G 24G 5% /home /dev/sda1 976M 266M 644M 30% /boot tmpfs 376M 1.2M 375M 1% /run/user/42 tmpfs 376M 4.6M 372M 2% /run/user/1000 /dev/sr0 6.7G 6.7G 0 100% /run/media/liuhongdi/CentOS-8-BaseOS-x86_64
#sed '1d' :删除第一行(表头)
#$1.. : 第1列..
#sed s/%//g : 替换百分号%为空
[liuhongdi@centos8 ~]$ df -h|sed '1d'|awk '{print $1,$5,$6}'|sed s/%//g |awk '{if($2>20) print $1,"used",$2"%",$3}' /dev/sda1 used 30% /boot /dev/sr0 used 100% /run/media/liuhongdi/CentOS-8-BaseOS-x86_64
2,查询挂载到/根目录且使用已用空间百分比大于0的分区
先看df的结果
[root@blog ~]# df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 7.5G 0 7.5G 0% /dev tmpfs 7.5G 0 7.5G 0% /dev/shm tmpfs 7.5G 500K 7.5G 1% /run tmpfs 7.5G 0 7.5G 0% /sys/fs/cgroup /dev/vda1 100G 14G 87G 14% / /dev/vdb1 500G 3.6G 497G 1% /databak tmpfs 1.5G 0 1.5G 0% /run/user/1000
查询
[root@blog ~]# df -h|sed '1d'|awk '{print $1,$5,$6}'|sed s/%//g |awk '{if($2>0 && $3=="/") print $1,"used",$2"%",$3}' /dev/vda1 used 14% /
五,awk应用例子之二:用户管理
1,查询所有使用bash做为shell的用户
说明;有登录bash的权限就存在风险,一般的用户是使用/sbin/nologin作为shell
#-F: 指定列的分隔符是冒号:
[liuhongdi@centos8 ~]$ grep '/bin/bash' /etc/passwd | awk -F: '{print $1}' root liuhongdi
用第7列指定/bin/bash也可以
[root@blog ~]$ awk -F: '$7=="/bin/bash"' /etc/passwd | awk -F: '{print $1}'
2,得到所有系统用户(uid<1000)
[root@blog ~]$ awk -F: '$3 < 1000' /etc/passwd
六,awk应用例子之三:nginx日志分析
1,访问量最高的前10个IP
#sort: 排序
#uniq:去除重复的行,
#uniq: -c或--count 在每列旁边显示该行重复出现的次数
#sort:排序
#sort -k1 :按第一个列进行排序
#sort -k1 -nr: n:按数字排序 -r:倒排
#head -n10: 取前10行
[root@blog nginxlogs]# awk '{print $1}' file_meet.access_log |sort | uniq -c |sort -k1 -nr |head -n10
2,访问量大于100的IP
[root@blog nginxlogs]# awk '{print $1}' file_meet.access_log |sort |uniq -c |sort -k1 -nr | awk '{if ($1 > 100) print}'
3,指定时间范围内访问量最高的10个ip
#$4>="[11/May/2020:08:00:00" && $4<="[11/May/2020:08:59:59"
#用来指定一个时间段
[root@blog nginxlogs]# awk '$4>="[11/May/2020:08:00:00" && $4<="[11/May/2020:08:59:59"' file_meet.access_log | awk '{print $1}' file_meet.access_log |sort | uniq -c |sort -k1 -nr |head -n10
4,统计访问次数最高的前10个url
[root@blog nginxlogs]# awk '{print $7}' file_meet.access_log |sort|uniq -c|sort -k1 -rn|head -n10
5,前一分钟的访问次数
#date=$(date -d '-1 minute' +%d/%b/%Y:%H:%M):
#得到前一分钟的时间
#-vdate=$date: 定义一个变量,变量名是date
#'$4>="["date":00" && $4<="["date":59"' :从前一分钟时间:00到前一分钟时间:59
#wc -l :统计有多少行
[root@loadserver nginxlogs]$ date=$(date -d '-1 minute' +%d/%b/%Y:%H:%M);awk -vdate=$date '$4>="["date":00" && $4<="["date":59"' ilc_ssl.access.log | wc -l
6,前5分钟的访问次数
注意两个变量的获取:
时间的定义必须与nginx的日志格式一致,否则会导致不能得到数据
[root@loadserver nginxlogs]$ date_begin=$(date -d '-6 minute' +%d/%b/%Y:%H:%M);date_end=$(date -d '-1 minute' +%d/%b/%Y:%H:%M);awk -v date_begin=$date_begin -v data_end=$date_end '$4>="["date_begin":00" && $4<="["date_end":59"' ilc_ssl.access.log | wc -l
说明:date 的-d参数,用来通过字符串的描述得到时间
-d, --date=STRING
display time described by STRING, not ‘now’
附:date的时间格式:
%d day of month (e.g, 01) %b locale’s abbreviated month name (e.g., Jan) %H hour (00..23) %M minute (00..59) %Y year
这个时间可以通过date的手册来获取
[root@loadserver nginxlogs]$ man date
7,统计每个URL访问内容的总大小
#处理完成后,以行文本后执行,一般用来处理输出结果
#可以看到awk默认是以空格区分的列,
#第7列是url,第10列是$body_bytes_sent
[root@blog nginxlogs]$ awk '{a[$7]++;size[$7]+=$10}END{for(i in a)print a[i],size[i],i}' file_meet.access_log
8,统计每个ip出现404的数量
[root@blog nginxlogs]$ awk '{if($9~/404/)a[$1" "$9]++}END{for(i in a)print i,a[i]}' file_meet.access_log
9,打印出所有报404错误的url
[root@loadserver nginxlogs]$ awk '($9 ~ /404/)' ilc_ssl.access.log |awk '{print $9, $7}' |sort
10,查日志中盗链的url
[root@loadserver nginxlogs]$ awk -F" '($2 ~ /.(jpg|gif|png)/ && $4 !~ /^https://www.ilc.com/ && $4 != "-") {print $4}' ilc_ssl.access.log | sort |uniq -c |sort
七,awk应用例子之四:网络管理
1,用awk查询得到ip地址
[root@loadserver nginxlogs]$ ip addr show eth0 | awk -F "[ /]+" '/inet /{print $3}' 172.17.173.28
也可用ifconfig(所属软件包已不更新,不建议使用)
[root@loadserver nginxlogs]$ ifconfig eth0 | awk -F "[ :]+" '/inet /{print $4}' 172.17.173.28
2,循环打印所有网络设备的ip
[root@blog nginxlogs]$ for dev in $(awk -F : '{if(NR>2)print $1}' /proc/net/dev);do printf '%+10s: ' $dev;echo $(ip addr show $dev | awk -F "[ /]+" '/inet /{print $3}'); done; eth0: 172.17.165.21 lo: 127.0.0.1
3,打印当前网络的连接状态:
说明:netstat命令已停止更新,不建议使用
[root@loadserver nginxlogs]$ netstat -an|awk '/^tcp/{++S[$NF]}END{for(a in S) print a,S[a]}' TIME_WAIT 122 CLOSE_WAIT 1 FIN_WAIT2 7 ESTABLISHED 124 SYN_RECV 1 LISTEN 30
建议大家应该使用效率更高的ss命令
#-t :表示只显示 TCP 套接字
#-n:表示显示数字地址和端口(而不是名字)
#-a:display all sockets
[root@loadserver nginxlogs]$ ss -tan|awk 'NR>1{++S[$1]}END{for (a in S) print a,S[a]}' SYN-RECV 1 ESTAB 109 FIN-WAIT-2 7 TIME-WAIT 135 LISTEN 30
补充:直接使用ss的统计功能也可以
[root@loadserver nginxlogs]$ ss -s Total: 249 (kernel 341) TCP: 217 (estab 106, closed 75, orphaned 6, synrecv 0, timewait 75/0), ports 280 Transport Total IP IPv6 * 341 - - RAW 0 0 0 UDP 12 12 0 TCP 142 142 0 INET 154 154 0 FRAG 0 0 0
八,awk应用例子之五:安全:
1,统计所有登录失败的ip的失败次数
[root@loadserver ~]# grep "Failed" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c
说明:也可以用lastb查看登录失败的情况
#sed '2,$d':删除最后的两行,一行是空行,一行是btmp的信息
[root@loadserver ~]# lastb | sed '2,$d' | awk '{ print $3}' | sort | uniq -c | sort -nr 1 101.200.12.118
2,列出所有用密码成功登录的用户和ip
[root@loadserver ~]# grep "Accepted password" /var/log/secure | awk '{print $(NF-5),$(NF-3)}'
3,列出所有用密钥成功登录的用户和ip
[root@blog ~]# grep "Accepted publickey" /var/log/secure | awk '{print $(NF-7),$(NF-5)}'
4,列出所有成功登录过的ip
[root@blog ~]# grep Accepted /var/log/secure | awk '{print $11}' | sort | uniq
九,查看nginx版本
[root@blog ~]# cat /etc/redhat-release CentOS Linux release 8.0.1905 (Core)