使用awk轻松玩转文本数据统计

我想应该先看看awk程序基本结构,pattern { action },基本操作就是一行行进行文本扫描,找出匹配模式的行,然后执行相应的动作,所有行读取完毕结束。

先看一个最简单的例子,trace.log文件包含姓名、年龄、工龄。
star 25 1
moon 32 5
sun 29 3
river 27 4
lake 30 6
sea 35 8

你现在想找出工龄大于等于5年的员工(整行),一句话的事,在pattern部分直接写你需要的表达式,$0用来标识一整行

awk '$3 >= 5 {print $0}' trace.log

1
结果:
moon 32 5
lake 30 6
sea 35 8

你想给输出加个行号,一点也不过分,awk提供了内建变量 NR

awk '$3 >= 5 {print NR,$0}' trace.log

1
结果:
2 moon 32 5
5 lake 30 6
6 sea 35 8

你想使用printf格式化输出下,那是你自己的事

awk '$3 >= 5 {printf("name: %s,age: %d \n",$1,$2)}' trace.log

1
结果酱紫:
name: moon,age: 32
name: lake,age: 30
name: sea,age: 35

通常使用awk都是只有action,输出你关心的分段数据,其实绝妙之处还是在pattern,你只想看看姓名是moon的数据

awk '$1 == "moon"' trace.log        # moon 32 5

1
pattren可以使用组合,使用括号,与&&,或||,非!

awk '$2 >30 && $3 >= 8' trace.log    # sea 35 8

1
说了这么多,还是没有意思,也许统计会对你有些许用处,首先你要明白两点:END关键字用于匹配最后一行之后的位置,你可以在创建自己的变量用于计算但无需声明。你想看下工作年限超过5年的有几个人

awk '$3 >= 5 {total += 1} END {print "超过5年:",total,"人"}' trace.log

1
一行一行的扫描像极了循环,循环过程中你可以开始你的表演(计算),END匹配到最后一行之后,然后搞点动作

现在你学会求和了,你想看看员工的平均年龄,别忘了NR记录了行数

awk '{total += $2} END {print total/NR}' trace.log

1
你想看看年龄的一般水平,也许中位数更具有代表性,你应该先排个序

awk '{print $2," ", $3," " $1}' trace.log | sort

1
接着找到中间位置的数据就OK了

awk '{print $2," ", $3," " $1}' trace.log | sort | awk '{line[NR] = $1} END {print line[int(NR/2)]}'

1
你还想看看年龄的最大值,最小值,有了上面的经验,简直不要太esay

awk '{print $2," ", $3," " $1}' trace.log | sort | awk '{line[NR] = $0} END {print line[1],"\n",line[NR]}'

还有一个BEGIN关键字没有说,和END类似,不赘述了,画个图总结下:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43275277/article/details/125105301