第一节:awk简介
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。擅长去列,计算,数组,统计,判断,循环。
第二节:awk的常用内置变量
FS 设置输入列分隔符,等价于命令行 -F选项
OFS 输出列分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
NF 浏览记录的列的个数
NR 已读的记录数(行号)
FNR 读取两个文件分别显示行号
$0变量是指整条记录。$1表示当前行的第一个域,$2表示当前行的第二个域,......以此类推。
$NF是number finally,表示最后一列的信息,跟变量NF是有区别的,变量NF统计的是每行列的总数
实例:
[root@lb03 ~]# cat file.txt
/etc/sysconfig/network
[root@lb03 ~]# awk 'BEGIN{RS="/"}{print $0}' file.txt -->将/替换成了换行符
etc
sysconfig
network
[root@lb03 ~]# awk 'BEGIN{ORS="/"}{print $0}' file.txt -->将换行符替换为/
/etc/sysconfig/network/[root@lb03 ~]#
第三节:awk的处理方式
1.BEGIN{}{}END{}
[root@lb03 ~]# awk 'BEGIN{print 1 + 1}{print $0}END{print "文件内容显示结束"}' /etc/hosts
2
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
文件内容显示结束
2.内置变量的使用
awk引用内部变量 -v 定义一个变量
[root@lb03 ~]# awk -va=10 -vb=20 'BEGIN{print a + b}'
30
3.变量的传递使用
[root@m01 /scripts]# IP=10.0.0.1 ———>定义外部变量IP
[root@m01 /scripts]# awk -v I=$IP 'BEGIN{print I}' ———>将外部变量IP传递给内置变量I
10.0.0.1
第四节:awk结合正则用法
#匹配第四列中含有98的行
[root@lb03 ~]# awk -F: '$4 ~/98/' passwd
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
#匹配第四列中没有98的行(取反)
[root@lb03 ~]# awk -F: '$4 !~/98/' passwd
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
Awk示例1:解释其下列命令的含义
# awk '/west/' datafile
# awk '/^north/' datafile
# awk '$3 ~ /^north/' datafile
# awk '/^(no|so)/' datafile
# awk '{print $3,$2}' datafile
# awk '{print $3 $2}' datafile
# awk '{print $0}' datafile
# awk '{print "Number of fields: "NF}' datafile
# awk '/northeast/{print $3,$2}' datafile
# awk '/^[ns]/{print $1}' datafile
# awk '$5 ~ /\. [7-9]+/' datafile
# awk '$2 !~ /E/{print $1,$2}' datafile
# awk '$3 ~ /^Joel/{print $3 "is a nice boy."}' datafile
# awk '$8 ~ /[0-9][0-9]$/{print $8}' datafile
# awk '$4 ~ /Chin$/{print "The price is $" $8 "."}' datafile
# awk '/Tj/{print $0}' datafile
# awk -F: '{print "Number of fields: "NF}' /etc/passwd
# awk -F "[ :]" '{print NF}' /etc/passwd
Awk示例2
[root@qls ~]# cat b.txt
web qiudao:is a:good boy!
[root@qls ~]# awk '{print NF}' b.txt
4
[root@qls ~]# awk -F ':' '{print NF}' b.txt
3
[root@qls ~]# awk -F"[ :]" '{print NF}' b.txt
6
第五节:awk的比较表达式
1.比较表达式
> 大于
< 小于
>= 大于等于
<= 小于等于
== 等于
!= 不等于
2.实例
#双条件判断是否管理员用户
[root@lb03 ~]# awk -F: '$1 == "root" && $3 == 0 ' passwd
root:x:0:0:root:/root:/bin/bash
#统计系统用户有多少个
[root@lb03 ~]# awk -F: '$3 > 0 && $3 < 1000 {print $1}' passwd |wc -l
21
[root@lb03 ~]# awk -F: '$3 > 0 && $3 < 1000 {i++}END{print i}' passwd
21
#统计普通用户数量
[root@lb03 ~]# awk -F: '$3 >= 1000 {i++}END{print i}' passwd
10
#把用户的uid的值乘于10小于100的显示出来
[root@lb03 ~]# awk -F: '$3 * 10 < 100{print $1}' passwd
bin
daemon
adm
第六节:awk结合语句用法
1.if else 判断语句
打印系统管理员用户的数量
[root@lb03 ~]# awk -F: '{if($3==0){i++}}END{print "管理员用户的数量为:"i}' passwd
管理员用户的数量为:2
打印系统管理员的数量和其他用户的数量
[root@lb03 ~]# awk -F: '{if($3==0){i++}else {j++}}END{print "当前系统管理员用户数量为:"i;print "其他用户数量为:"j}' passwd
当前系统管理员用户数量为:2
其他用户数量为:29
打印系统管理员的数量和系统用户的数量及普通用户的数量
[root@lb03 ~]# awk -F: '{if($3==0){i++} else {if($3>0 && $3<1000){j++} else {o++}}}END{print "管理员用户的数量为:"i " 系统用户的数量为:"j" 普通用户的数量为:",o}' passwd
管理员用户的数量为:2 系统用户的数量为:19 普通用户的数量为: 10
2.for循环语句
创建10个用户
[root@lb03 ~]# awk 'BEGIN{for(i=1;i<=10;i++){print "useradd old"i}}' |bash
修改日期同时并创建一个文件
[root@lb03 ~]# awk 'BEGIN{for(i=1;i<15;i++){print "date -s 2019/11/"i" && touch file-"i".txt"}}' |bash
3.while 循环语句用法
创建10个用户
[root@lb03 ~]# awk 'BEGIN{i=1;while(i<10){print "useradd new"i;i++}}' |bash
第七节:awk数组
1.统计passwd文件中所有shell的数量
count ===== echo ${!count[*]} ---->即索引下标
[root@lb03 ~]# awk -F: '{count[$NF]++}END{for (i in count)print i,count[i]}' passwd |sort -rnk2 |column -t
/sbin/nologin 17
/bin/bash 11
/sbin/shutdown 1
/sbin/halt 1
/bin/sync 1
2.取出tcp的11种状态的数量
[root@lb03 ~]# ss -ant |awk 'NR>1{state[$1]++}END{for (i in state)print i,state[i]}'
LISTEN 4
ESTAB 1
3.取出访问日志中每个ip的访问次数
[root@lb03 ~]# awk '{ips[$1]++}END{for (i in ips)print i,ips[i]}' access.log |sort -rnk2 |head -4|column -t
139.226.172.217 16033
47.102.42.79 1041
180.95.238.82 994
113.140.249.33 727
4.统计系统日志secure.log,破解密码失败的ip的次数
[root@lb03 ~]# awk '/Failed password/{ips[$(NF-3)]++}END{for (i in ips)print i,ips[i]}' secure.log |sort -rnk2 |head -4|column -t
218.65.30.25 68652
218.65.30.53 34326
218.87.109.154 21201
112.85.42.103 18065
5.统计访问日志中每个ip的访问次数和每个ip对应返回的字节数量。
[root@lb03 ~]# awk '{ips[$1]++;he[$1]+=$10}END{for (i in ips)print i,ips[i],he[i]}' access.log |sort -rnk2 |head -4|column -t
139.226.172.217 16033 749869585
47.102.42.79 1041 16462
180.95.238.82 994 154136
113.140.249.33 727 105270
#它们拥有相同的索引ip
6.每个IP访问状态码数量-->将$1和$9共同作为数组count的索引
[root@m01 /scripts]# awk '{count[$1" "$9]++}END{for (i in count)print i,count[i]}' access.log |sort -rnk3 |column -t |head
139.226.172.217 200 14731
47.102.42.79 200 1041
180.95.238.82 302 992
139.226.172.217 304 805
113.140.249.33 302 726
223.166.74.124 302 646
112.87.125.55 200 450
182.138.163.167 302 429
223.166.74.198 302 351
182.138.158.169 302 308
awk的字符串替换
https://www.jianshu.com/p/d90f8a2ecd62