awk命令详解

作者 : 开心源码 本文共2353个字,预计阅读时间需要6分钟 发布时间: 2022-05-13 共212人阅读

写在最开始

相比于sed,awk就显得强大多了。假如说sed是轻巧的山地摩托,那awk就是装甲坦克,分分钟把sed碾碎。awk的复杂性和高功能性在于:

  1. 支持扩展正则语法
  2. 语法规则更丰富和复杂,大量内置变量和灵活自己设置变量
  3. 输出控制舒适,定制型极高
  4. 逻辑、流程、内置函数功能齐全
    总之awk已经不能用命令来描述了,awk可以说是一门语言,专门为行数据解决而生,其高效性和机动性不言而喻。

记录和域

awk把输入行进行了结构化解决,通过制定分隔字符(用内置变量FS指定),把输入行(记录)分成若干个,如下所示:

# input.txtzhangsanfeng 70 1.87 wudangzhangwuji 20 1.85 mingjiaozhouzhiruo 18 1.65 emeiyuanzhen 40 1.73 shaolin

上面的文件中的每一行都是一条记录,单独拿出来一条记录时,又分为4个域,分别指代了:名字,年龄,身高,帮派,在awk命令中可以用$1 $2 $3 $4来引用每个域,用$0来表示这条记录(原汁原味,保留原来的所有字符),有了这些铺垫,我们即可以更方便的对每个域进行判断、计算、输出。
默认情况下分隔符是空格 TAB 或者其以任意数量(至少1个)、任意次序的组合,即多个空格会被认为是一个分隔符。

输出和格式化

awk的输出方式和C语言几乎一样,语法和符号也几乎一致。总结起来有以下几点:

  1. 用print输出时,输出变量假如用逗号分隔,那么输出的变量间默认为一个空格符。
  2. 用print输出时,默认最后会输出一个换行符。
  3. 用print输出时,输出变量用空格分隔,那么输出变量间相互紧邻。
  4. 用printf输出时,输出格式完全由自己控制,最后也不会自动输出换行。

我们就上面的input.txt来进行一点展现。
图1.1中我么用逗号分隔要输出的变量$1 $2 $3 $4,输出结果自动会用空格符来分隔,如图1.2所示,不用逗号分隔输出结果就不会有分隔,而紧邻在一起。

图1.1 用逗号分隔要输出的变量图1.2 不用逗号分隔的情况

图1.3所示,我们在第2个域和第3个域间插入一个逗号,在第3个域和第4个域间插入一个下划线,在记录的结尾插入换行符,都能直观的在结果中展现。图1.4中展现了更漂亮的输出控制,符号用于控制该域左对齐输出(默认右对齐输出),符号-后面的数字表示该域至少占的字符宽度(多了往后排,少了用空格补满),符号.和格式化符%f搭配,用于输出保留多少位的小数(会四舍五入)。

图1.3 printf完全控制图1.4 控制对齐方式和域所占宽度

除了以上的格式化控制符,还有如下,仅把他列出来,不做逐个分析。

%c:ASCII字符%e:科学技术输出%o:八进制输出%x:十六进制输出

可以使用的变量类型

同sed一样,awk中变量也没有类型,也有两个值:整数值和字符值。我把awk中所有变量分为几类来分别说明:

  1. 普通变量(自己设置变量)
    在说明普通变量前,先来讲一下awk的基本结构。如下所示:
BEGIN {#这个左花括号必需和END在同一行,别问,问就规定,读入数据前执行一次。}{# 对于每条记录,都要经过这个主体}END {#这个左花括号必需和END在同一行,别问,问就规定,解决完所有数据后执行一次。}

由上面可以得知,awk执行的时候,大致可以分为三个阶段:BEGIN,主体,END。BEGIN最先执行,END最后执行,且都只执行一次。主体部分对于每行记录都要执行一次。
自己设置变量推荐放在BEGIN中定义,这样比较清晰。如下所示,计算所有人的年龄的平均值。

计算平均年龄

上图的total就属于自己设置变量,使用名字即可以直接引用。至于上面的NR就是我们接下来要讲的内置变量了。

  1. 内置变量

除了可以自定变量,awk实际还内置了很多变量,一来方便客户使用,二来,awk自己执行的时候也需要频繁用到这些变量,所以在定义自己的变量时,命名注意别和内置变量相同。内置变量的使用上和普通变量毫无差别。主要有如下常用的内置变量:

$0 1 2...:引用记录的域FILENAME:记录来自哪个文件FNR:浏览文件的记录数NR:当前记录数,如同和FNR一样,number of recordFS:域分隔符,默认空格或者TAB或者其任意组合,field separationOFS:输出分隔符,默认空格,output field separationNF:当前记录中的域数量,number of fieldARGC:命令行参数个数ARGV:命令行参数存放的数组,从0起

如下图所示:域分隔符被设置为字符h,输出分隔符为___,第一条记录:
z h angsanfeng 70 1.87 wudang
h分隔为两个部分,所以在输出$3的时候没有任何东西。第三条记录:
z h ouz h iruo 18 1.65 emei
h分隔为三个部分,输出的时候,每个部分用OFS=___连接。

内置变量的使用

  1. 数组

awk中的数组的索引可以是字符串,也可以是数字,并且假如数字09和字符串“09”索引到的是不同元素。其实awk中的数组更像键值可以是任意类型的map。awk中提供了一种访问顺序未知的数组遍历方式:

for (i in arr){    #do something,i is the key,not the value}if ("zhangsanfeng" in arr){    #do something}

数组的简单使用

更多情况,我们用数组是用来解决字符串,比方在函数split中,对记录进行分割后,分割的字段就存放在数组中,下标从1起。

函数split的用法

  1. 命令行参数

除了内置变量和自己设置变量,客户还可以通过命令行来传递参数给脚本,如下所示:

命令行参数

数据解决函数

  • gsub:替换字符串

正则替换普通替换

  • length:返回字符串的长度

image.png

  • match:检测能否包含匹配式

image.png

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » awk命令详解

发表回复