awk基本用法、awk应用案例及综合脚本

一、awk命令

●可以对文本实现精确搜索并输出 ,逐行处理

用法:

1,前置指令 | awk 选项  条件  指令

2,awk 选项  条件  指令  被处理文档

选项:-F 定义分隔符

指令:print   打印、输出

条件:/字符串/

内置变量:$1第一列  $2第二列  $3第三列 ...$0 所有列   NR行号   NF 列号

 1.1 准备素材

[root@test1 ~]# echo "hello the world" > abc.txt  
[root@test1 ~]# echo "welcome to hangzhou" >> abc.txt 
[root@test1 ~]# cat abc.txt    #准备素材1
hello the world
welcome to hangzhou

[root@test1 ~]# cp /etc/passwd user #准备素材2

1.2 awk命令运用

[root@test1 ~]# awk '{print}' abc.txt    #输出所有
hello the world
welcome to hangzhou

[root@test1 ~]# awk '/to/{print}' abc.txt    #输出有to的那行
welcome to hangzhou

[root@test1 ~]# awk '{print $2}' abc.txt    #输出所有行的第2列
the
to

[root@test1 ~]# awk '/to/{print $1}' abc.txt    #输出有to的那行的第1列
welcome

[root@test1 ~]# awk '{print $0}' abc.txt    #输出所有行所有列
hello the world
welcome to hangzhou

[root@test1 ~]# awk '{print $0,$1}' abc.txt  #输出所有行所有列,第1列
hello the world hello
welcome to hangzhou welcome

[root@test1 ~]# awk '{print NR}' abc.txt   #输出所有行的行号
1
2

[root@test1 ~]# awk '{print NR,$0}' abc.txt   #输出所有行的行号,所有列
1 hello the world
2 welcome to hangzhou

[root@test1 ~]# awk '{print NR,NF}' abc.txt   #输出所有行的行号,列号(有几列)
1 3
2 3
[root@test1 ~]# awk '/^bin/{print NR}'  user    #找以bin开头的行,显示该行的行号
2

[root@test1 ~]# awk '/^bin/{print NR,$0}'  user   #找以bin开头的行,显示该行的行号,所有列
2 bin:x:1:1:bin:/bin:/sbin/nologin

[root@test1 ~]# awk '{print NF}'   user   #输出所有行的列号(每行有几列)
1
1
1
1
1

[root@test1 ~]# awk -F: '{print $1}'  user   #文档中如果没有空格,可以用F修改分隔符
root
bin
daemon
adm
lp

[root@test1 ~]# awk -F: '{print $1,$6}'  user    #使用冒号作为列的分隔符,显示第1、6列
root /root
bin /bin
daemon /sbin
adm /var/adm
lp /var/spool/lpd

[root@test1 ~]# awk -F: '{print $1" 的家目录是 "$6}'  user    #还可以输出常量,加双引号即可
root 的家目录是 /root
bin 的家目录是 /bin
daemon 的家目录是 /sbin
adm 的家目录是 /var/adm
lp 的家目录是 /var/spool/lpd

[root@test1 ~]# awk -F: '{print $1" 的解释器是 "$7}'  user
root 的解释器是 /bin/bash
bin 的解释器是 /sbin/nologin
daemon 的解释器是 /sbin/nologin
adm 的解释器是 /sbin/nologin
lp 的解释器是 /sbin/nologin

1.3 收集根分区剩余容量

[root@test1 ~]# df -h | awk  '/\/$/{print  $4}'    #使用df  -h 作为前置指令交给awk处理找到以/结尾的行,并输出第4列
46G

[root@test1 ~]# df -h | awk  '/\/$/{print  "根分区剩余容量是"$4}'  #然后加常量输出
根分区剩余容量是46G

1.4 收集网卡流量信息

[root@test1 ~]# ifconfig ens192 | awk '/RX p/{print "ens192网卡接收的数据量是"$5"字节"}'
ens192网卡接收的数据量是107209996字节
[root@test1 ~]# ifconfig ens192 | awk '/TX p/{print "ens192网卡发送的数据量是"$5"字节"}'
ens192网卡发送的数据量是22857468字节

二、awk的条件

2.1 /字符串/

●可以使用正则    ~ 包含   !~不包含

[root@test1 ~]# awk -F: '$6~/root/{print}'  user  #输出第6列包含root的行
root:x:0:0:root:/root:/bin/bash

[root@test1 ~]# awk -F: '$6~/bin/{print}'  user   #输出第6列包含bin的行
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

[root@test1 ~]# awk -F: '$6!~/bin/{print}'  user  #输出第6列不包含bin的
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

2.2 使用数字或者字符串

==  !=  >  >=  <  <=

[root@test1 ~]# awk -F: '$3<3{print}' user   #输出第3列小于3的行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

[root@test1 ~]# awk -F: '$3<=3{print}' user   #输出第3列小于等于3的行
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

[root@test1 ~]# awk -F: 'NR==2{print}' user   #输出第2行
bin:x:1:1:bin:/bin:/sbin/nologin

[root@test1 ~]# awk -F: 'NR>2{print}' user    #输出行号大于2的行
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

2.3 逻辑组合

 &&并且   ||或者

[root@test1 ~]# awk -F: 'NR==2||NR==4{print}' user   #找行号是2或者4的行
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

[root@test1 ~]# awk -F: 'NR==2||NR==40{print}' user   #如果只有一个条件满足就显示一个
bin:x:1:1:bin:/bin:/sbin/nologin
#找第7列包含bash并且第3列小于等于500的行
[root@test1 ~]# awk -F: '$7~/bash/&&$3<=500{print}' user 
root:x:0:0:root:/root:/bin/bash

[root@test1 ~]# awk 'NR==2&&NR==4{print}' user   #找行号既是2又是4的行,不存在,无输出

[root@test1 ~]# awk -F: '$7~/bash/&&NR<=3{print}' user  #找第7列包含bash并且行号是1~3的
root:x:0:0:root:/root:/bin/bash

[root@test1 ~]# awk -F: '$7~/bash/||NR<=3{print}' user  #找第7列包含bash或者行号是1~3的
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

2.4  awk处理时机

●可以执行额外任务

BEGIN任务  执行1次,读取文档之前执行

逐行任务   执行n次,读取文档时执行 

END任务   执行1次,读取文档之后执行

用法格式:BEGIN{ 任务1 }{ 任务2 }END{ 任务3 }

[root@test1 ~]# awk -F: 'BEGIN{print "ok"}{print $1}END{print "ok"}' user
ok
root
bin
daemon
adm
lp
ok
[root@test1 ~]# awk 'BEGIN{print NR}{print NR}END{print NR}' user
0
1
2
3
4
5
5

1)利用awk处理时机,输出下列内容

 单命令输出

[root@test1 ~]# awk 'BEGIN{print "User\tUID\tHome"}'   #第1步输出表头信息
User	UID	Home
[root@test1 ~]# awk -F: '{print $1"\t"$3"\t"$6}' user    #第2步输出内容
root	0	/root
bin	1	/bin
daemon	2	/sbin
adm	3	/var/adm
lp	4	/var/spool/lpd
[root@test1 ~]# awk 'END{print "总计"NR"行" }' user    #第3步输出结尾
总计5行

 合并命令输出

[root@test1 ~]# awk -F: 'BEGIN{print "User\tUID\tHome"}{print $1"\t"$3"\t"$6}END{print "总计"NR"行"}' user
User	UID	Home
root	0	/root
bin	1	/bin
daemon	2	/sbin
adm	3	/var/adm
lp	4	/var/spool/lpd
总计5行

三、awk综合脚本

●使用awk数组+for循环实现高级搜索

数组:相当于可以存储多个值的特殊变量

数组名[下标] = 下标对应的值

3.1  案例运用

[root@test1 ~]# awk 'BEGIN{a[1]=10;a[2]=20;print a[2],a[1]}'  #使用awk测试数组,首先创建数组a,下标1对应值是10,下标2对应值是20,然后输出下标是2与下标是1的值
20 10

[root@test1 ~]# awk 'BEGIN{a["abc"]="abcabc";a["xyz"]="xyzxyz";print a["xyz"]}'  #数组的下标和值都可以不是数字,测试时加双引号即可
xyzxyz

以上信息是手工输入,实际情况中通常是从文档收集

准备一个文档,里面有6行,每行分别是abc、xyz、abc、opq、xyz、abc  然后

按照awk逐行处理的工作特点使用awk  '{a[$1]++}'  shu.txt 走完每一行得到下列结果

但不会输出到屏幕

a[$1]++    a[abc]++   a[abc]=1

a[$1]++    a[xyz]++   a[xyz]=1

a[$1]++    a[abc]++   a[abc]=2

a[$1]++    a[opq]++   a[opq]=1

a[$1]++    a[xyz]++    a[xyz]=2

a[$1]++    a[abc]++   a[abc]=3

如果要输出到屏幕可以使用命令awk  '{a[$1]++}END{print a["abc"]}'  shu.txt

3.2 awk和for循环结合

根据上述操作得知使用数组可以收集信息,但收集完了之后查看确不方便,可以用for循环实现。方法如下:

for(变量名 in 数组名){print 变量名}    #这个格式可以查看数组的所有下标

awk '{a[$1]++}END{for(i in a){print i,a[i]}}' shu.txt   #使用逐行任务与数组收集文档shu.txt中的信息,然后在END任务中使用for循环显示所有数组a的下标与值



awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' /var/log/httpd/access_log   #将上述的文件替换成网站的日志,就可以最终用来查看日志得到可以得到哪个ip来访以及来访的次数



awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' /var/log/httpd/access_log | sort  -nr  -k  2    #使用sort命令增加排序功能,-n是以数字形式排序,-r是降序, -k是指定为第几列排序

3.3 综合脚本案例

◆编写脚本,可以查看系统的各种参数信息

[root@test1 ~]# vim xtcs.sh
#!/bin/bash
while :
do
clear
free -h | awk  '/^Mem:/{print "剩余内存容量是"$4}'
df -h | awk  '/\/$/{print "根分区剩余容量是"$4}'
awk 'END{print "用户总数是"NR"个"}'  /etc/passwd
who | awk 'END{print "登录用户数量是"NR"个"}'
uptime | awk '{print "cpu的15分钟平均负载是"$NF}'
rpm -qa | awk 'END{print "安装的软件包数量是"NR"个"}'
sleep 3
done

[root@test1 ~]# chmod u+x xtcs.sh 
[root@test1 ~]# ./xtcs.sh 
剩余内存容量是6.6G
根分区剩余容量是46G
用户总数是34个
登录用户数量是2个
cpu的15分钟平均负载是0.05
安装的软件包数量是413个
剩余内存容量是6.6G
根分区剩余容量是46G
用户总数是34个
登录用户数量是2个
cpu的15分钟平均负载是0.05
安装的软件包数量是413个
循环执行
........
........
........
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值