awk 是除了 sed 命令之外,Linux 系统中另一个功能比较强大的数据处理工具。
和 sed 命令类似,awk 命令也是逐行扫描文件(从第一行到最后一行),寻找含有目标文本的行,如果匹配成功,则会在该行上执行用户想要的操作;否则不对行做任何处理。
awk 在读取文件内容的每一行时,将对比该行是否与给定的模式相匹配,如果匹配,则执行处理过程,否则对该行不做任何处理。如果没有指定处理脚本,则把匹配的行显示到标准输出,即默认处理动作是 print 打印行;如果没有指定模式匹配,则默认匹配所有的数据。
awk 有两个特殊的模式:BEGIN 和 END,它们被放置在没有读取任何数据之前以及在所有的数据读取完成以后执行。在读取文件内容前,BEGIN 后面的指令将被执行,然后读取文件内容并判断是否与特定的模式匹配,如果匹配,则执行正常模式后面的动作指令,最后执行 END 模式命令,并输出文档处理后的结果。
awk 的工作流程图如图 1 所示。
图 1 awk的工作流程图
awk 命令基本语法格式如下:
[root@bogon ~]# awk [选项] '脚本命令' 文件名
awk 命令常用选项及其功能如表 2 所示。
表 2 awk命令常用选项及其功能
选 项
功 能
-F fs
指定以 fs 作为输入行的分隔符,awk 命令默认分隔符为空格或制表符
-f file
从脚本文件中读取 awk 脚本指令,以取代在命令参数中输入处理脚本
-v var=val
在执行处理过程之前,设置一个变量 var,并给其设备初始值为val
-W compat
使用兼容模式运行 awk, GUN 扩展选项将被忽略
-W copyleft
输出简短的 GUN 版权信息
-W dump-variables[=file]
打印全局变量(变量名、类型、值)到文件中,如果没有提供文件名,则自动输出到名 为 dump-variables 的文件中
awk 的脚本命令主要由 2 部分组成,分别为匹配规则和执行命令。
awk 的匹配规则,和 sed 命令中的 address 部分作用相同,用来指定脚本命令可以作用到文本内容中的具体行,可以使用字符串或者正则表达式指定。另外,整个脚本命令是使用的单引号(' '),而其中的执行命令部分需要使用花括号“{}”括起来。
注意,在 awk 程序执行时,如果没有指定执行命令,则默认会把匹配的行输出;如果不指定匹配规则,则默认匹配文本中所有的行。
awk 的主要特性之一是其处理文本文件中数据的能力,它会自动给每行中的每个数据元素分配一个变量。
awk 的内置变量及功能如表 3 所示。
表 3 awk的内置变量及功能
变 量
功 能
$0
当前记录
$1~$n
当前记录的第 n 个字段
ARGC
命令行参数个数
FILENAME
当前输入文档的名称
FNR
当前输入文档的当前记录编号,尤其是当有多个输入文档时有用
NR
输入流的当前记录编号
NF
当前记录的字段个数
FS
字段分隔符
OFS
输入字段分隔符,默认为空格
ORS
输入记录分隔符,默认为换行符 \n
RS
输入记录分隔符,默认为换行符 \n
【例 1】输出当前文档的当前行编号。
创建 1 个样本文件,命名为 text,在样本文件中写入如下内容:
http://www.weixueyuan.net
1234
在终端页面中输入如下命令:
[root@bogon ~]# awk '{print FNR}' text
1
2
3
表达式由变量、常量、函数、正则表达式和操作符组成,awk 中变量有字符变量和数字变量。如果在 awk 中定义的变量没有初始化,则初始值为空字符或 0。当字符操作时必须加引号。操作符及含义如表 3 所示。
表 3 常用操作符及含义
操作符
含义
+
加
-
减
*
乘
/
除
%
求余
^
幂运算
++
自加1
--
自减1
+=
相加后赋值给变量
=
相减后赋值给变量
氺=
相乘后赋值给变量
/=
相除后赋值给变量
>
大于
<
小于
>=
大于或等于
<=
小于或等于
=
等于
!=
不等于
〜
匹配正则表达式
!〜
不匹配正则表达式
&&
与
II
或
例如 awk 赋值运算符,a+5 等价于 a=a+5,如下所示:
[root@bogon ~]# awk 'BEGIN{a=2; a+=2;print a}'
4
除此之外,awk 还支持 if 条件判断、while 和 for 循环语句等。
1) if 条件判断语句。if 语句基本格式有两种:
if(表达式)
动作1
else
动作2
或者
if(表达式) 动作1;else 动作2
如果表达式的判断结果为真,则执行动作 1,否则执行动作 2。
例如,判断 boot 分区可用容量小于 20MB 时报警,否则显示 OK,如下所示:
[root@bogon ~]# df | grep "boot" | awk '{if ($4<20000) print "Alert"; else print "OK"}'
OK
2) while 循环语句。while 循环语句基本格式有两种:
while(条件)
动作
或者
do
动作
while(条件)
while 循环语句如下所示:
[root@bogon ~]# awk 'i=1 {} BEGIN { while(i<=10) {++i; print i}}'
1
2
3
4
......
10
11
3) for循环语句。for 循环语句基本格式如下:
for(变量;条件;计数器)
动作
for 循环语句如下所示:
[root@bogon ~]# awk 'BEGIN { for(i=1; i<=10; i++) print i}'
1
2
3
......
9
10