awk 报告生成器

awk 名称来自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母 awk 是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息 注意: 1. awk 处理过程: 依次对每一行进行处理,然后输出 2. awk 更适合格式化文本,对文本进行较复杂的格式处理 3. 语法:awk [options] 'Pattern{Action}' file,file1... awk [选项]‘模式{动作}’ file file1

awk 内置变量
变量 说明
FS 指定输入字段分隔符,默认为空白字符
OFS 指定输出字段分隔符,默认为空白字符
RS 指定换行符(输入换行符),指定输入时的换行符,默认为回车键
ORS 指定换行符(输出换行符),指定输出时的换行符,默认为回车键
NF 分割的字段数量
NR 行号
FNR 分别计数每个文件的行号
FILENAME 当前文件名
ARGV 数组
ARGC 数组的长度,即命令行参数的个数

1. 内置变量 NR、NF、FNR 举例 NR:行号,NF:分割的字段数量

FNR:分别计数每个文件的行号

2. 内置变量 RS、ORS 举例 RS:指定换行符(输入换行符),指定输入时的换行符,默认为回车键 ORS:指定换行符(输出换行符)

3. 内置变量 FILENAME 举例 FILENAME:当前文件名 4. 内置变量 ARGC、ARGV举例 ARGV:数组 ARGC:数组的长度,即命令行参数的个数 5. 自定义参数

awk 内置函数

一:算数函数

常用算数函数 说明
rand 产生 6 位数的随机数
srand 产生变化的 6 位随机数
int 可用于截取整数部分

二:字符串函数

常用字符串函数 说明
gsub 改变所有符合匹配条件的字符
sub 改变符合匹配条件的第一个字符
length 获取字符串
index 获取字符所在位置
split 分割字符串
asort 排序
asorti 函数通过下标进行排序

有下面例子可以看出,gsub 可以改变所有匹配到字符,而 sub 只改变匹配到的第一个字符,所以 gsub 可以理解为全局变量,sub可以理解为局部变量 length 输出字段的长度,默认返回值为输出整行的长度 split 可以将字符串按照指定字符串切割,结合 for 循环,赋值到数组,从而形成动态数组 asort 根据元素的值进行排序 asort 排序时会重新生成下标 asorti 函数通过下标进行排序

awk 基础

注意: 1. 内置变量

内置函数 说明
$0 整行
$NF 分割后的最后一列
NF 分割后的段数
$(NF-1) 倒数第二列

2. 内置函数的外侧不能加双引号,否则会当做文本输出打印出来

语法:awk [options] 'Pattern{Action}' file action 指的是动作,最常用的动作为:print、printf,用于格式化后输出文本 好的,知道了简单的语法后我们就开始举例了 一:print 打印文本内容 直接使用 print 动作,相当于 cat 命令 获取相关列,awk 默认空格为分隔符,$1 与 $5 之间的 “,” 表示空格,即表示第 1,5 列 当最后一列数值为空时,取值时也会为空。由下例可知 $(NF-1) 表示每行的倒数第二位,因为 awk 是以 为单位处理脚本的 添加组合,内置函数的外侧不能加双引号,否则会当做文本输出打印出来 验证 split 数组的下标 注意:split 函数分割后的数组元素下标是从 1 开始的 二:awk 分隔符 注意:FS,OFS 为内置变量,-F、-v 为 awk 的参数 1. 输出分隔符 指定输出分隔符:-F、-v FS="#" 2. 输入分隔符 指定输入分隔符:-v OFS="---",看到例子应该明白了吧,OFS 默认是以空格为分割的,此处可以结合 -v FS 来修改指定分隔符

三:awk 格式化 使用 printf 来完善 awk 的格式化能力 注意: 1. 使用 printf 动作输出的文本不会换行,如果需要换行,可以在对应的 “ 格式替换符 ” 后加入 “ \n ” 进行转义 2. 使用 printf 动作时,“ 指定的格式 ” 与 “ 被格式化的文本 ” 之间,需要用 “ 逗号 ” 隔开 3. 使用 printf 动作时,“ 格式 ” 中的 “ 格式替换符 ” 必须与 “ 被格式化的文本 ” 相互对应

awk 模式

一:空模式 如下图中框框位置为空,即为空模式 二:关系运算模式 关系运算符举例 关系运算符 ' ~ ' 结合正则举例,其中 $2 表示第二列,$2~/正则/ 表示文中第二列如果与正则匹配就执行相应的动作

三:BEGIN,END 模式 表头、表内容、表尾 四:正则模式 注意:awk 中正则需要 / / 内 匹配以 sys 开头的用户 匹配以 /bin/bash 结尾的用户 使用扩展正则表达式(亲测 centOS7.4,Ubuntu16.04 中在使用 {x,y} 时不需要 --posix 或 --re-interval 配合)不过尽量使用来配合扩展正则表达式吧 五:行范围模式 通过字符匹配范围行,即匹配第一次出现的字符 x 到第一次出现的字符 y 之间的行 通过行号匹配范围行

awk 语法结构

一:if(条件){语句;语句1 ...} else if(条件){语句;语句1 ...} else{语句;语句1 ...} 二:语法一:for(初始化; 布尔表达式; 更新){语句} 语法二:for(变量 in 数组) {代码语句} 三:while( 布尔表达式 ) {语句} 四:do {代码语句}while(条件) 注意:do...while... 循环语句,即使不符合条件也会先执行一次 五:continue 跳出 “当前” 循环,break 跳出 “整个” 循环 六:exit 与 next exit 跳出 “整个 awk 命令” next 跳过当前行

三元运算

注意:可以替代 if 语句中的 if(条件){语句;语句1 ...} else{语句;语句1 ...} 语法 1. 如图中例子,若条件为真,则用 系统用户:A 普通用户:B 来表示 2. 统计 /etc/passwd 用户个数 3. 打印奇偶行 注意: 1. awk 中,如果省略了模式对应的动作,当符合条件时,默认动作为打印整行,即{print $0} 2. awk 中,0 或空字符表示 “假”,非 0 或非空字符表示 “真” 如下: awk '{print $0}' one.txt 中,动作 {print $0} 前没有任何模式,并不表示空字符,而是表示 空模式,输出的没行都满足条件,匹配后的结果为真,即输出文本中的每行 明白了上面的内容,我们来打印 奇偶行 就容易理解了 最后我们再来看一下 i 的值是多少 awk数组 注意: awk 中数组的下标可以是数字也可以是字符串(需要加双引号) awk 中数组的下标默认是从 1 开始的 awk 中数组的本质是关联数组 1. 简单的数组 可以通过下标数字来取值,如:第一个例子 第二个例子说明空字符串是合法的 在直接引用不存在的元素时,awk 会自动创建一个空字符串,如:第三个例子 2. 判断数组是否存在 3. 使用 delete 删除数组 4. 数组结合 for 循环实现遍历输出 5. 实战 统计同一个 ip 出现的次数 统计每个名字出现的次数