UC头条:linux初探:文字处理工具awk
之前更新了linux初探Json处理工具之jq,发现挺有意思的,索性将awk、grep、sed等都给总结一下。
什么是awk
(资料图片)
这里的awk,在linux系统下,我们一般指的是gawk,是GUN利用awk来创建的一门编程语言,符合POSIX1003.1标准,主要是用于文字处理,为此我们简称awk,在linux系统中,一般替我们做了软连接,我们可以通过whereis一路找下去,即可找到gawk或者其他版本的awk。
并不是所有的linux系统都是预装了gawk的
点击加载图片
我们为什么需要awk
对于有取相应列需求的,我们使用awk在合适不过了,这也是使用awk最多的操作之一,这里,我们举了一个不是例子的例子,因为要证明一个东西确实被“需要”,是很困难的,没有什么是不可替代的。
需求分析
我们准备一个文本信息,我们想取出其中黄色部分勾选出来的内容
点击加载图片
shell脚本
我们先使用shell脚本来写这个需求,具体流程为
先读取一行
以空格为分割,获取行数有多少列
输出最后一列
根据需求分析,我们很快便顺利编写了脚本
点击加载图片
我们执行脚本查看结果
点击加载图片
awk命令
我们将上述操作,使用awk来写,仅需一句awk"{print$NF}"即可,具体逻辑,我们在案例中讲解。
点击加载图片
希望通过这个例子,能够了解,我们为什么要学习使用awk,不仅是因为可以在同事面前装一波,更重要的是能够节省大量的时间。
awk工作流程
当我们想获取某个文件,假设以空格分开,获取第多少列,这个时候,就非awk莫属了,它的工作流程简单梳理,可以理解为如下模式。
点击加载图片
其实我们将awk分为3个块,分别是BEGIN语句块、END语句块和主体语句块,其具体工作流程如下
执行BEGIN语句块
重复从文件/标准输入中读取一行,执行pattern语句块,直至文件结尾/标准输入结束
最后执行END语句块
其语法如下
BEGIN{#BEGIN语句块}{#主体语句块print$0}END{#END语句块}
其中,BEGIN和END语句块可以被忽略。
从最简单开始
awk内置变量
$num:每行获取的num列,若为0,则代表整行
FS:自定义分隔符,在命令行,可以使用-F来指定
NF:列数量
NR:行数
提取文档的第一列
例如上面的文案,我们想提取文档的第一列出来
点击加载图片
在awk中,我们使用$来取具体的列,比如第一列:$1,第二列$2,以此类推。
要输出第一列,我们使用print即可。
很轻松,我们可以顺利用命令写出求出第一列
命令:awk"{print$1}"
点击加载图片
这个命令就是我们忽略了BEGIN以及END,我们补充完整是这样的。
点击加载图片
我们使用awk-f来从文件读取awk指定且运行指令。
点击加载图片
指定分隔符
在awk中,默认是以空格作为分隔符,但是我们可以指定自定义分隔符,例如我们想获取/etc/passwd中的用户名,但是该文件是以:作为分割的,文件内容如下:
点击加载图片
在进行awk切割中,我们使用FS作为指定自定义分隔符,该操作需要定义在BEGIN语句块中,我们编写下awk指令
点击加载图片
我们使用命令行,则可以使用-F来指定分隔符,例如:
点击加载图片
这里提及一点,若有多个分隔符,可以使用-F=[]来定义,若我们即想设置:为分隔符,又想设置空格为分隔符,即可设置为-F=[.]
读取文档最后一列
我们可以使用NF变量,读取文档最后一列,我们同样拿/etc/passwd为例,我们想获取用户的默认shell
即以:分割的最后一列
点击加载图片
我们可以使用命令awk-F":""{print$NF}"来获取
点击加载图片
$NF的具体逻辑是什么呢?
NF是awk的内置变量,其记录了该行按照预设的分隔符进行划分,其记录的具体列数,将值放入NF中,而使用$num获取第num列的数据,而该num我们代入NF则是最后一列。
我们通过例子说明
点击加载图片
通过案例,我们可以验证,NF仅仅是记录了该行按照预设定义的分隔符进行分割后的列数。
给文件前增加一个行号
NR是记录awk处理的行数,我们可以使用该内置变量来打印行数,例如:
我们还是使用pdudo_awk_test.txt为案例,打印一下行数
命令:awk"{printNR":"$0}"
点击加载图片
NR内置变量作用不止于此,例如,我们可以处理第100行到120行,就可以使用NR进行控制。
总结
在文章中,我们了解了什么是awk,以及谈论了一下我们为什么需要awk,总之,在列文本处理这块awk非常棒,而后在一些案例中,我们也看到了比较简单的awk操作,awk不仅是命令行,也是一门编程语言,所以也有其条件判断if、以及循环for等,我们后期再介绍。
标签: