我们之前已经学习了awk
的基本操作,可以熟练的对文档进行切列,做基本操作是不成问题的,这次我们看下awk
处理后续,本篇文章主要以讲述awk
编程为主。
变量
在awk
中,变量不需要提前声明,直接使用即可,我们在使用过程中,会通过其值判断其类型。例如我们这样定义整数、字符串、浮点数、数组等,注意awk
中并不区分全局变量和局部变量,每一个定义的都是全部变量,这点尤其注意。
# 整形 a = 10; # 字符串 b = "pdudo"; # 浮点数 c = 3.14; # 数组(其实底层应该是hashmap) d[0] = "123"; d["pdudo"] = 4; d[2] = 3.14;
数组这块讲一下,awk
应该和bash
是一样的,对于数组,底层是利用hashmap
来存储的,而非开辟一块连续的空间。
我们来尝试一下,定义如上几个变量,然后进行处理,最后再输出变量信息
我们执行一下该awk
脚本
在awk
中还内置了一些变量,后续我们再使用过程中逐步讲解。
数组
如上所述,其实在awk
中和shell
一样,我们定义数组,其实底层应该是在操作hashmap
,所以我们定义数组是这样的,array[key]=value
。
我们在删除一个数组或者数组元素,使用delete
即可,例如,删除数组array: delete array
、删除数组元素index: delete array[index]
我们来写下数组的定义和删除
执行代码
控制语句
if ... else
在awk
中可以使用if...[else]
作为逻辑判断,为节省语法,还可以使用三目运算符。
语法
if (条件判断) { 代码块 } else { 代码块 }
我们来写一个简单的if
语句看下
执行代码
和c语言一样,在使用if
进行条件判断中,else
语句块不是必须写的。
循环语句
在最开始变量处,我们已经写了一个for
循环,那是针对数组的,这次我们可以看下其他循环语句。
while
while (条件判断) { 代码块 }
do ... while
do 代码块 while (条件判断)
这里while
和do..while
的区别为,while
是先进行条件判断,再执行语句,而do ... while
是先执行语句,后判断,导致的结果是: do...while
总是会执行一次循环中的代码块。
for(var in array)
for (变量 in 数组) { 代码块 }
for (expr1;expr2;expr3)
for (expr1;expr2;expr3) { 代码块 }
这里,for
循环也有2种,第一种是为了遍历数组的 ,第二种才是我们熟知的for
语言,其中判断逻辑和c语言类似。
我们这里使用除遍历数组外的循环,来获取1+2+....100
的和
代码
我们执行代码后结果
在循环中,也有break
和continue
等语法,这里就不不解释了。
自定义函数
若我们想自定义函数,其语法为
function names(...) { 函数主体 }
其中,function
是关键字,name
是函数名称,而后...
是函数参数,多个参数用逗号,
分割,而后大括号中{}
是我们编写的函数主体。
我们举个例子说明
我们定义函数,传入参数 x,y
返回x*y-1
的值
代码
我们执行代码
案例
前面介绍了awk
变量、数组 以及 流程控制 和 自定义函数,我们来利用awk
来写一些案例。
统计linux服务器的tcp
状态
代码编写
通过netstat -a
管道执行该awk
代码解析
在awk
中,我们使用了数组,数组的key
就是我们tcp
的State
,值是我们出现的次数,所以说,我们使用++
来自增,在统计完后,我们再END
代码块使用遍历数组的方式,将数据输出,便可得到统计,指的注意的是,在BEGIN
处,我们使用了内置变量OFS
, 我们再介绍一下其姊妹
FS
: 这个我们介绍过, 是设置字段分隔符的
RS
: 设置记录分割符的,默认是回车
而OFS
和ORS
是输出的时候字段分隔符和记录分割符的。
为方便理解这几个概念,我们做一个小案例
我们准备一个文件
cat text.txt 1abc2abc3abcdef 7abc8abc9abcdef andabcenenabc123abcdef ➜
现在我们以abc
作为字段分隔符,将def
作为记录分隔符,然后输出前3列。
得到结果如下
若我们设置OFS
和ORS
呢,会控制输出的格式,例如
而在主体的/^tcp/
则进行匹配,以tcp
开头的段。
日志分析
例如有日志文件如下
利用awk
工具,将包含getContent
且运行时间小于5.5s的日志,将其完整日志输出出来。
我们可以编写如下awk
代码
我们执行后输出如下
关于我们awk
内置函数split
,其原型如下
split( s , a [ , r] )
s 是字符串
a 是将我们拆分的数据放入数组中
r 是分隔符,若为空,则使用FS
代替
总结
awk
作为一个工具或者是作为一门语言,很复杂,单靠几篇文章很难讲清楚,总之,有总感觉,看了很多资料,看了很多文档,但是涉及到知识点过多,想讲清楚,不容易,得到的结果就是断断续续的,哎,就这样吧。