linux初探:文字处理工具awk (2)

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

我们之前已经学习了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 (条件判断)

这里whiledo..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的和

代码

我们执行代码后结果

在循环中,也有breakcontinue等语法,这里就不不解释了。

自定义函数

若我们想自定义函数,其语法为

function names(...) {
  函数主体
}

其中,function是关键字,name是函数名称,而后...是函数参数,多个参数用逗号,分割,而后大括号中{}是我们编写的函数主体。

我们举个例子说明

我们定义函数,传入参数 x,y 返回x*y-1的值

代码

我们执行代码

案例

前面介绍了awk变量、数组 以及 流程控制 和 自定义函数,我们来利用awk来写一些案例。

统计linux服务器的tcp状态

代码编写

通过netstat -a管道执行该awk

代码解析

awk中,我们使用了数组,数组的key就是我们tcpState,值是我们出现的次数,所以说,我们使用++来自增,在统计完后,我们再END代码块使用遍历数组的方式,将数据输出,便可得到统计,指的注意的是,在BEGIN处,我们使用了内置变量OFS, 我们再介绍一下其姊妹

FS: 这个我们介绍过, 是设置字段分隔符的

RS: 设置记录分割符的,默认是回车

OFSORS是输出的时候字段分隔符和记录分割符的。

为方便理解这几个概念,我们做一个小案例

我们准备一个文件

cat text.txt
1abc2abc3abcdef
7abc8abc9abcdef
andabcenenabc123abcdef
➜  

现在我们以abc作为字段分隔符,将def作为记录分隔符,然后输出前3列。

得到结果如下

若我们设置OFSORS呢,会控制输出的格式,例如

而在主体的/^tcp/则进行匹配,以tcp开头的段。

日志分析

例如有日志文件如下

利用awk工具,将包含getContent且运行时间小于5.5s的日志,将其完整日志输出出来。

我们可以编写如下awk代码

我们执行后输出如下

关于我们awk内置函数split,其原型如下

split( s , a [ , r] )

s 是字符串

a 是将我们拆分的数据放入数组中

r 是分隔符,若为空,则使用FS代替

总结

awk作为一个工具或者是作为一门语言,很复杂,单靠几篇文章很难讲清楚,总之,有总感觉,看了很多资料,看了很多文档,但是涉及到知识点过多,想讲清楚,不容易,得到的结果就是断断续续的,哎,就这样吧。

posted @ 2022-06-29 21:12  pdudos  阅读(0)  评论(0编辑  收藏  举报  来源