Linux三剑客之awk实战详解教程(转载)
我们知道 Linux 三剑客,它们分别是:grep、sed、awk。在前边已经讲过和,没看过的同学可以直接点击阅读,今天要分享的是更为强⼤
的awk。
sed 可以实现⾮交互式的字符串替换,grep 能够实现有效的过滤功能。与两者相⽐,awk 是⼀款强⼤的⽂本分析⼯具,在对数据分析并⽣成报告时,显得尤为强悍。
awk 强⼤的功能,是⼀般 Linux 命令⽆法⽐拟的。在本⽂中,我不会告诉你 awk 也是⼀种编程语⾔,免得会吓到你。我们只需把它当做Linux 下⼀款强⼤的⽂本分析⼯具即可。
这篇⽂章,我仍然秉持着实⽤、实践原则,提供⼤量的⽰例,但不会⾯⾯俱到。通过本⽂可以帮助你,快速将 awk 运⽤起来,这些东西⾜够应付⼯作中⼤多数应⽤场景。
场景
学习具体使⽤前,先来看下 awk 能⼲些什么事情:
1.能够将给定的⽂本内容,按照我们期望的格式输出显⽰,打印成报表。
2.分析处理系统⽇志,快速地分析挖掘我们关⼼的数据,并⽣成统计信息;
3.⽅便地⽤来统计数据,⽐如⽹站的访问量,访问的 IP 量等;
4.通过各种⼯具的组合,快速地汇总分析系统的运⾏信息,让你对系统的运⾏了如指掌;
5.强⼤的脚本语⾔表达能⼒,⽀持循环、条件、数组等语法,助你分析更加复杂的数据;
……
当然 awk 不仅能做这些事情,当你将它的⽤法融汇贯通时,可以随⼼所欲的按照你的意愿,来进⾏⾼效的数据分析和统计。
不过我们需要知道,awk 不是万能的,它⽐较擅长处理格式化的⽂本,⽐如⽇志、csv格式数据等;
原理
我们先来简单了解 awk 基本⼯作原理,通过下边的图⽂讲述,希望你能了解 awk 到底是如何⼯作的。
awk 基本命令格式
结合下图来详细说明 awk ⼯作原理
⾸先,执⾏关键字BEGIN标识的{}中的命令;
完成BEGIN⼤括号中命令的后,开始执⾏body命令;
逐⾏读取数据,默认读到\n分割的内容为⼀条记录,其实就是⾏的概念;
将记录按照指定的分隔符划分为字段,其实就是列的概念;
循环执⾏body块中的命令,每读取⼀⾏,执⾏⼀次body,最终完成body执⾏;
最后,执⾏END命令,通常会在END中输出最后的结果;
awk 是输⼊驱动的,有多少输⼊⾏,就会执⾏多少次body命令。
我们在下边的⽰例学习中,要时刻记着:记录(Record)就是⾏,字段(Field)就是列,BEGIN是预处理阶段,body是 awk 真正⼯作的阶
段,END是最后处理阶段。
实战 - ⼊门
从下边内容开始,我们直接进⼊到实战。为了⽅便举例,我先把如下信息保存到
好了,我们先来⼀个最简单最常⽤的 awk ⽰例,输出第 1、4、8 列:
⼤括号⾥边的就是 awk 语句,只能被单引号包含,其中,$1..$N表⽰第⼏列,$0表⽰整个⾏内容
再来看下awk⽐较实⽤的功能格式化输出。和C语⾔的printf格式输出是⼀⽑⼀样,我个⼈特别喜欢这种格式化⽅式,⽽不是C++中的流的⽅式。
%s表⽰字符串占位符,-4表⽰列宽度为4,且左对齐,我们还可以根据需要,列出更复杂的格式来,这⾥先不详细举例了。
实战 - 进阶
(⼀)过滤记录
有些数据可能不是你想要的,可以根据需要进⾏过滤
上边的过滤条件为,第 3 列为 root 且第 6 列为 10 的⾏,才会被输出。
awk ⽀持各种⽐较运算符号!=、>、<、>=、<=,其中$0表⽰整⾏的所有内容。
(⼆)内置变量
awk 内置了⼀些变量,更⽅便我们对数据的处理
过滤第 3 列为 root ⽤户,以及第 2 ⾏内容,且打印时输出⾏号。NR表⽰当前第⼏⾏,NF表⽰当前⾏有⼏列。
(三)指定分隔符
我们的数据,不总是以空格为分隔符,我们可以通过FS变量指定分隔符。
我们指定分隔符为2019,这样就将⾏内容分割为了两部分,将2019替换成了*
上边的命令也可以通过-F选项指定分割符
如果你需要指定多个分隔符,可以这样做-F '[;:]'。相信聪明的你,⼀定能够理解并融会贯通的。
同样,awk 可以指定输出时的分隔符,通过OFS变量来设置
输出时,各字段⽤OFS指定的符号进⾏了分隔。
实战 - ⾼级
(⼀)条件匹配
列出 root ⽤户的所有⽂件,以及第⼀⾏⽂件
上边匹配第三列中包含root的⾏,~其实就是正则表达式的匹配。
同样,awk 可以像 grep ⼀样匹配某⼀⾏,就像这样
另外,可以这样/Aug|Dec/匹配多个关键词。
模式取反可以使⽤!符号
(⼆)拆分⽂件
我们来做⼀件有意思的事情,可以将⽂本信息拆分为多个⽂件,下边命令按照⽉份(第5列)将⽂件信息拆分为多个⽂件
awk ⽀持重定向符号>,直接将每⾏内容重定向到⽉份命名的⽂件了,当然你也可以把指定的列输出到⽂件
(三)if 语句
复杂的条件判断,可以使⽤ awk 的if语句,awk 的强⼤正因为它是个脚本解释器,拥有⼀般脚本语⾔的编程能⼒,下边⽰例通过稍微复杂的条件进⾏拆分⽂件
要注意,if语句是在⼤括号⾥边的。
(四)统计
统计当前⽬录下,所有*.c、*.h⽂件所占⽤空间⼤⼩总和
第 5 列表⽰⽂件⼤⼩,每读取⼀⾏就会将该⽂件⼤⼩计算到sum变量中,在最后END阶段打印出sum,也就是所有⽂件的⼤⼩总和。
再来看⼀个例⼦,统计每个⽤户的进程占⽤了多少内存,注意取值的是 RSS 那⼀列
这⾥⽤到了数组和for循环,值得⼀提的是,awk 的数组可以理解为字典或Map,key 可以是数值和字符串,这种数据类型在平时很常⽤。(五)字符串
通过下边简单⽰例,展⽰ awk 对字符串操作的⽀持
awk 内置⽀持⼀系列的字符串函数,length计算字符串长度,toupper函数转换字符串为⼤写。
实战 - 技巧
为了从整体上理解 awk ⼯作机制,我们再来看⼀个综合的⽰例,假设有⼀个学⽣成绩单:
由于此⽰例程序稍显复杂,在命令⾏上不易读,另外呢,也想通过此案例介绍另外⼀种 awk 的执⾏⽅式,我们的 awk 脚
本如下:
执⾏ awk 结果如下
我们可以将复杂的 awk 语句写⼊脚本⽂件cal.awk,然后通过-f选项指定从脚本⽂件执⾏。
在BEGIN阶段,我们初始化了相关变量,并打印了表头的格式
在body阶段,我们读取每⼀⾏数据,计算该学科和该同学的总成绩
在END阶段,我们先打印了表尾的格式,并打印总成绩,以及计算了平均值
这个简单⽰例,完整的体现了 awk 的⼯作机制和原理,希望通过此⽰例能够帮你真正理解 awk 是如何⼯作的。
总结归纳
通过上述的⽰例,我们学习到了 awk 的⼯作原理,下边我们来总结下⼏个概念和常⽤的知识点。
(⼀)内置变量
1.每⼀⾏内容记录,叫做记录,英⽂名称Record
2.每⾏中通过分隔符隔开的每⼀列,叫做字段,英⽂名称Field
明确这⼏个概念后,我们来总结⼏个重要的内置变量:
NR:表⽰当前的⾏数;
NF:表⽰当前的列数;
RS:⾏分隔符,默认是换⾏;
FS:列分隔符,默认是空格和制表符;
OFS:输出列分隔符,⽤于打印时分割字段,默认为空格
ORS:输出⾏分隔符,⽤于打印时分割记录,默认为换⾏符
(⼆)输出格式
awk 提供printf函数进⾏格式化输出功能,具体的使⽤⽅式和C语法基本⼀致。
基本⽤法
常⽤的格式化⽅式:
%d⼗进制有符号整数
%u⼗进制⽆符号整数
%f浮点数
%s字符串
%c单个字符
%e指数形式的浮点数
%x%X⽆符号以⼗六进制表⽰的整数
%0⽆符号以⼋进制表⽰的整数
%g⾃动选择合适的表⽰法
\n换⾏符
\t Tab符
(三)编程语句
awk 不仅是⼀个 Linux 命令⾏⼯具,它其实是⼀门脚本语⾔,⽀持程序设计语⾔所有的控制结构,它⽀持:
条件语句
循环语句
数组
函数
(四)常⽤函数
awk 内置了⼤量的有⽤函数功能,也⽀持⾃定义函数,允许你编写⾃⼰的函数来扩展内置函数。
这⾥只简单罗列⼀些⽐较常⽤的字符串函数:
index(s, t)返回⼦串 t 在 s 中的位置
正则匹配到第一个关键字就停止
length(s)返回字符串 s 的长度
split(s, a, sep)分割字符串,并将分割后的各字段存放在数组 a 中
substr(s, p, n)根据参数,返回⼦串
tolower(s)将字符串转换为⼩写
toupper(s)将字符串转换为⼤写
这⾥只简单总结⼀些常⽤的字符串功能函数,具体使⽤⽅法,还需要你参照前边的⽰例程序,举⼀反三,运⽤到实际问题中。本⽂转载于肖邦。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。