第五章:三剑客之awk

第一节: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

你可能感兴趣的:(第五章:三剑客之awk)