awk命令详解

写在最开始

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

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

记录和域

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

# input.txt
zhangsanfeng 70 1.87 wudang
zhangwuji 20 1.85 mingjiao
zhouzhiruo 18 1.65 emei
yuanzhen 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 record
FS:域分隔符,默认空格或TAB或其任意组合,field separation
OFS:输出分隔符,默认空格,output field separation
NF:当前记录中的域数量,number of field
ARGC:命令行参数个数
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
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • linux awk命令详解 来源:ggjucheng 链接:http://www.cnblogs.com/ggju...
    meng_philip123阅读 4,310评论 0 1
  • 简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤...
    ad085d162310阅读 4,761评论 0 1
  • 第一篇 awk简介与表达式实例 一种名字怪异的语言 模式扫描和处理,处理数据和生成报告。 awk不仅仅是linux...
    ___n阅读 11,903评论 0 23
  • 简介: awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得...
    机智的老刘明同志阅读 16,056评论 0 3
  • 背景 AWK是一种处理文本文件的语言,是一个强大的文本分析工具 awk的基本用法 文本内容: 2 this is ...
    ericsonyc阅读 2,720评论 0 0