查看原文
其他

正则表达式(11)-三剑客之awk(6)

Cloud研习社 Cloud研习社 2023-06-06

本节讲解awk函数。awk支持内置函数和自定义函数。


常见的内置函数


1. 对数字的处理:

rand() 返回0-1之间的随机数

srand() 配合rand()生成随机数的种子。即srand()和rand()必须同时使用才会生成随机数。

int() 返回一个整数

实例演示:

# rand()& srand()
[root@studyclub jason]# awk 'BEGIN{srand();print rand()}'
0.0269022
[root@studyclub jason]# awk 'BEGIN{srand();print rand()}'
0.755576


2. 对字符串的处理

length([s]) 返回字符串的长度

sub(r,s,[t]) 在 t 字符串中查找r(r可以是字符、字符串或模式匹配),并将查找到的第一个内容替换为s

gsub(r,s,[t]) 在 t 字符串中查找r(r可以是字符、字符串或模式匹配),并将查找到的全部内容替换为s

实例演示:

# sub
[root@studyclub jason]# date | awk 'sub(/:/,"-",$0)'
Mon Jul 26 13-18:49 CST 2021
[root@studyclub jason]# date | awk '{sub(/:/,"-",$0);print $0}'
Mon Jul 26 13-18:26 CST 2021

# gsub
[root@studyclub jason]# date | awk 'gsub(/:/,"-",$0)'
Mon Jul 26 13-21-16 CST 2021
[root@studyclub jason]# date | awk '{gsub(/:/,"-",$0);print $0}'
Mon Jul 26 13-21-23 CST 2021


split(s,array,[r]): 以 r  作为分隔符,把s字符串进行分割,第一个放到数组array下标为1的成员中,第二个放到数组array下标为2的成员中...依次类推。
实例演示:
# 统计连接到本机的ip地址,每个ip地址有多少个连接
# netstat -anpt的第五列是远端的ip和端口号,我们以分号作为分隔符,统计冒号前面的(即Program[1])ip地址出现的次数。
[root@studyclub jason]# netstat -anpt | awk '/^tcp/{split($5,Program,":");count[Program[1]]++}END{for(i in count)print i, count[i]}'
 5
127.0.0.1 1
0.0.0.0 4
10.0.0.136 1


system函数:通过system函数可以在awk中调用shell命令

[root@studyclub jason]# awk 'BEGIN{system("hostname")}'
studyclub

[root@studyclub jason]# awk 'BEGIN{system("cat /etc/issue")}'
\S
Kernel \r on an \m


这个时候,我们想到前面有个实例,就是把超过一定连接数的客户端的ip地址加入防火墙的黑名单(即iptables禁止该ip再连接本机)。我们通过system命令来试试:
[root@studyclub jason]# netstat -anpt | awk '/^tcp/{split($4,Program,":");count[Program[1]]++}END{for(i in count){if(count[i]>20){system("iptables -A INPUT -s "i -j "REJECT")}}}'


注意:如果system函数中需要用到awk的变量,可以使用空格分隔,除了awk的变量外,其他一律用双引号”“括起来。


自定义函数


自定义函数的格式:

function name (para1,para2,para3,...){
  statements
  return expression
}


实例演示:
[root@studyclub jason]# cat func_awk
function max(a,b){
  a>=b?var=a:var=b
  return var
}
BEGIN{dog=12;monkey=11;print max(dog,monkey)}
[root@studyclub jason]# awk -f func_awk
12



awk脚本


将awk程序直接写成脚本,直接调用,好处是不用每次都去敲复杂的awk程序。

实例演示:

# 实例1:我们把前面获取uid大于1000的用户名的例子改造一下:
[root@studyclub jason]# cat uid_awk
{if($3>=1000) {print $1,"common_user"}}
[root@studyclub jason]# awk -F: -f uid_awk /etc/passwd

# 实例2:上面例子还可以改成:
[root@studyclub jason]# cat uid_awk2
#!/bin/awk -f
{if($3>=1000) {print $1,"common_user"}}

[root@studyclub jason]# chmod u+x uid_awk2
[root@studyclub jason]# ./uid_awk2 -F: /etc/passwd
jason common_user
......
sun common_user


课后实践:
  • 请用awk从/etc/passwd中取出当前所有的用户名以及其对应的默认shell是哪个。取出以后,请统计每个不同的shell出现了几次。

  • 已知/mnt/iso下有许多的rpm包,每个包的命名类似下面的形式:libcap-2.22-9.el7.x86_64.rpm。我们知道这种文件名.rpm前面的x86_64 是代表该包支持的系统架构,如果我们想查看当前目录下的rpm都支持哪些系统类型,应该怎么做?(提示:用awk实现,配合sort、uniq处理结果)

  • 统计/etc/fstab中每个文件系统类型出现的次数

  • 生产场景实例(防止dos攻击):根据web日志或网络连接数,监控ip的并发连接数在某个时刻达到150以上,就通过防火墙封掉该ip,监控频率每8分钟一次。提示:防火墙封闭ip地址的命令:iptables -A INPUT -s IP -j REJECT

  • 有一个文本文件的内容如下,请将域名取出并计数排序

http://www.cloudstudyclub.com/index.html
http://www.cloudstudyclub.com/1.html
http://post.cloudstudyclub.com/index.html
http://mp3.cloudstudyclub.com/index.html
http://www.cloudstudyclub.com/3.html
http://post.cloudstudyclub.com/2.html
  • 使⽤awk命令,计算⼀个⽬录下⽂件⼤⼩的总和


PS:本篇文章是awk系列文章的最后一篇,请大家完成练习并牢牢掌握awk的用法。由于雷哥接下来的工作和充电任务比较重,所以2022年元旦之前就没有技术文章推送了,望大家理解,雷哥会想你们的。


手应知:

    尝鲜Rocky Linux

《Linux基础及进阶》:

   065 - 正则表达式(6)-三剑客之awk(1)    066 - 正则表达式(7)-三剑客之awk(2)    067 - 正则表达式(8)-三剑客之awk(3)    068 - 正则表达式(9)-三剑客之awk(4)   069 - 正则表达式(10)-三剑客之awk(5)


看完本文有收获?请分享给更多人


推荐关注「Cloud研习社」,带你从零开始掌握云计算技术!

微信号|bjdream-1


Cloud研习社 · 

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存