shell脚本awk工具

正则表达式 

\w        匹配数字、字母、下划线 

egrep "roo\w" user   //找roo后面是数字、字母、下划线的字符串


\s        匹配空格、tab键    

egrep "roo\s" user   //找roo后面是1个空格或者tab键打出来的空格的字符串,如果没有

就不输出

sed其他指令

a行下追加   i行上添加   c替换整行

sed 'a 666' user    //所有行的下面追加666
sed '1a 666' user   //第1行的下面追加666
sed '/^bin/a 666' user   //在以bin开头的行的下面追加666
sed 'i 666' user  //所有行的上面添加666
sed '5i 666' user   //第5行的上面添加666
sed '$i 666' user  //最后1行的上面添加666
sed 'c 666' user   //所有行都替换成666
sed '1c 666' user  //替换第1行为666

 awk

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

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

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

选项 -F 定义分隔符

指令 print

条件  /字符串/

内置变量  $1第一列  $2第二列  $3第三列 ...

                    $0 所有列   NR行号   NF 列号

[root@proxy opt]# cat abc.txt   //准备素材

hello the world

welcome to beijing

awk '{print}' abc.txt    //输出所有
awk '/to/{print}' abc.txt    //输出有to的那行
awk '{print $2}' abc.txt    //输出所有行的第2列
awk '/to/{print $1}' abc.txt    //输出有to的那行的第1列
awk '{print $0}' abc.txt    //输出所有行所有列
awk '{print $0,$1}' abc.txt  //输出所有行所有列,第1列
awk '{print NR}' abc.txt   //输出所有行的行号
awk '{print NR,$0}' abc.txt   //输出所有行的行号,所有列


awk '{print NR,NF}' abc.txt   //输出所有行的行号,列号(有几列)

awk '/^bin/{print NR}'  user    //找以bin开头的行,显示该行的行号
awk '/^bin/{print NR,$0}'  user   //找以bin开头的行,显示该行的
行号,所有列
awk '{print NF}'   user   //输出所有行的列号(每行有几列)
awk -F: '{print $1}'  user   //文档中如果没有空格,可以用F修改分
隔符
awk -F: '{print $1,$6}'  user    //使用冒号作为列的分隔符,显示
第1、6列
awk -F: '{print $1" 的家目录是 "$6}'  user    //还可以输出常量,加双引号即可
root 的家目录是 /root
bin 的家目录是 /bin
daemon 的家目录是 /sbin
adm 的家目录是 /var/adm
lp 的家目录是 /var/spool/lpd

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

收集根分区剩余容量 

df -h | awk  '/\/$/{print  $4}'    //使用df  -h 作为前置指令交给awk处理
找到以/结尾的行,并输出第4列
df -h | awk  '/\/$/{print  "根分区剩余容量是"$4}'   //然后加常量输出
收集网卡流量信息
ifconfig eth0 | awk '/RX p/{print "ens33网卡接收的数据量是"$5"字节"}'
ifconfig eth0 | awk '/TX p/{print "ens33网卡发送的数据量是"$5"字节"}'

awk的条件 

1,/字符串/   还可以使用正则    ~ 包含   !~不包含
awk -F: '$6~/root/{print}'  user  //输出第6列包含root的行
awk -F: '$6~/bin/{print}'  user   //输出第6列包含bin的行
awk -F: '$6!~/bin/{print}'  user  //输出第6列不包含bin的行

使用数字或者字符串
==  !=  >  >=  <  <=
awk -F: '$3<3{print}' user   //输出第3列小于3的行
awk -F: '$3<=3{print}' user   //输出第3列小于等于3的行
awk -F: 'NR==2{print}' user   //输出第2行
awk -F: 'NR>2{print}' user    //输出行号大于2的行
逻辑组合  &&并且   ||或者
awk -F: 'NR==2||NR==4{print}' user   //找行号是2或者4的行
awk -F: 'NR==2||NR==40{print}' user   //如果只有一个条件满足就显示一个
awk -F: '$7~/bash/&&$3<=500{print}' user   //找第7列包含bash并且第3列小于等于500的行
awk 'NR==2&&NR==4{print}' user   //找行号既是2又是4的行,不存在,无输出
awk -F: '$7~/bash/&&NR<=3{print}' user  //找第7列包含bash并且行号是1~3的
awk -F: '$7~/bash/||NR<=3{print}' user  //找第7列包含bash或者行号是1~3的


awk -F: '$1~/root/' user    //找第1列包含root的行如果有用户叫root6,也会搜到,比较宽松的搜索方式,如果任务就是{print}的话可以省略不写
awk -F: '$1=="root"' user  //找第1列完全等于root的行多一个字符少一个字符都不行,比较严格的搜索方式


运算
awk 'NR%2==0{print NR,$0}' user   //在条件中使用运算,找到将行号除以2余数等于0的行,然后输出该行的行号和所有列,相当于输出偶数行

awk处理时机,可以执行额外任务

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

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

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

BEGIN{ 任务1 }{ 任务2 }END{ 任务3 }

awk -F: 'BEGIN{print "ok"}{print $1}END{print "ok"}' user

awk 'BEGIN{print NR}{print NR}END{print NR}' user

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

awk 'BEGIN{print "User\tUID\tHome"}'   //第1步输出表头信息
awk -F: '{print $1"\t"$3"\t"$6}' user    //第2步输出内容
awk 'END{print "总计"NR"行" }' user    //第3步输出结尾

awk -F: 'BEGIN{print "User\tUID\tHome"}{print $1"\t"$3"\t"$6}END{print "总计"NR"行"}' user   //合在一起写


使用awk统计网站访问量

setenforce 0    //关闭selinux

systemctl stop firewalld  //关闭防火墙

systemctl restart httpd  //开启网站服务

使用浏览器多访问几次网站,包括本机用curl

curl  192.168.4.110:82    //如果端口没改过就不用敲

awk  '{print $1}'  /var/log/httpd/access_log   //初步统计,不完美

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

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

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

awk 'BEGIN{a[1]=10;a[2]=20;print a[2],a[1]}'    //使用awk测试数组,首先创建数组a,下标1对应值是10,下标2对应值是20,然后输出下标是2与下标是1的值
awk 'BEGIN{a["abc"]="abcabc";a["xyz"]="xyzxyz";print a["xyz"]}'   //数组的下标和值都可以不是数字,测试时加双引号即可

以上信息是手工输入,实际情况中通常是从文档收集准备一个文档,里面有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

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

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

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

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

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

/var/log/httpd/access_log :网站日志文件存放位置

 测试:另外建立一台主机,配置Ip地址,搭建httpd服务,访问ip为110的httpd网址。然后测试统计次数。

 

 默认是升序   n:降序     K:第几列


/var/log/secure是安全日志,如果有人登陆时输入错误密码的话信息会记录下来,这种信息可以用awk抓取出来,方法如下: 


awk '/Failed password for root/{ip[$11]++}END{for(i in ip){print i,ip[i]}}' /var/log/secure    //统计安全日志中访问root账户密码输入错误的ip地址与次数

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

#!/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    //每执行一次休息3秒
done

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值