跳到主要内容

06、AWK 基本使用实例

本章节,我们使用一些常见的实例来介绍 AWK 的一些常见用法。

在我们继续之前,请先确保当前目录下存在一个文件 employee.txt,里面的内容如下

1)  张三  技术部  23
2)  李四  人力部  22
3)  王五  行政部  23
4)  赵六  技术部  24
5)  朱七  客服部  23

AWK 中的列/字段和列编号

AWK是一个行处理器,但是却是一个列输出器。对于 AWK 来说,默认的分割符是空白符号,包括 "\t" 和空格 " "。

而且,当 AWK 使用分割符对每一行进行分割后,会对每一列/字段进行编号,取名 $ 1 $ 2 $ 3 $ 4,所见即所得的第一列,第二列,第三列.....

$ 0 则表示一整行。

于是,上面的文本编列如下

$1  $2   $3     $4

1)  张三  技术部  23    $0

AWK 输出某列或者某个字段

之前的代码,我们都是使用 print $ 0 来输出整行,其实,我们可以用 print $ column_n 来输出一列或者其中的某些列。

例如,如果要输出第二列,也就是名字列,则可以使用 print $ 2

例如,如果我们要输出第一列和第三列,且使用制表符作为列分割符,则可以使用 print $ 1 "\t" $ 3

注意 "\t" 必须使用双引号引起来.

[www.ddkk.com]$ awk '{print $1 "\t" $3}' employee.txt

运行上面的代码,输出结果如下

1)  技术部
2)  人力部
3)  行政部
4)  技术部
5)  客服部

AWK 输出所有的行

我们前面有提到,AWK 的主体代码包括两大部分,模式和 AWK 语句

/pattern/ {awk-commands}

模式和语句都是可选的,但,必须存在其一。它们之间有几大规则

1、 模式部分,是正则字符串匹配;
2、 AWK语句部分,是模式部分匹配成功后要执行的语句;
3、 如果模式部分省略,则默认每一行都匹配,也就是每一行都会被AWK语句执行;
4、 如果语句部分省略,那么默认的语句就是输出行,也就是print $ 0;

例如,下面的 awk 命令,用于输出行总包行 “术” 的行

[www.ddkk.com]$ awk '/术/ {print $0}' employee.txt

运行上面的代码,输出结果如下

1)  张三  技术部  23
4)  赵六  技术部  24

因为AWK 语句部分可以省略,因此,上面的命令可以参略为

[www.ddkk.com]$ awk '/术/' employee.txt

运行上面的代码,输出结果如下

1)  张三  技术部  23
4)  赵六  技术部  24

AWk 输出匹配模式的某些列

需要注意的是,/pattern/ 模式匹配是针对整行的,从某些方面说,是针对 $ 0 的。

我们还可以在行匹配模式之后,输出其中的某一列或者某几列。

例如,下面的命令,在行匹配之后,输出第二列和第三列,并且使用制表符分隔。

[www.ddkk.com]$ awk '/术/ {print $1 "\t" $3}' employee.txt

运行上面的命令,输出结果如下

1)  技术部
4)  技术部

AWK 任意顺序输出列

因为AWK 对每一列的分割在 BEGIN 语句执行完毕后就已经分割好了,因此我们在 AWK 主体代码中可以按照任意顺序把 $ 0.... $ n 传递给 print 函数

比如我们要想要先输出第三列,然后输出第一列,那么可以使用下面的命令

[www.ddkk.com]$ awk '/术/ {print $3 "\t" $1}' employee.txt

运行上面的代码,输出结果如下

技术部 1)
技术部 4)

AWK 统计和输出满足模式的行

AWK中的所有变量都不需要实现初始化,因为 AWK 发现它们如果没有初始化,则会自动初始化为 0

因此我们可以使用 {++count} 或者 {count++} 或者 {count = count+1} 来统计行数

[www.ddkk.com]$ awk '/术/ {count = count+1} END {print "Count = ", count}' employee.txt

运行上面的命令,输出结果如下

Count =  2

AWK 条件:输出总长度大于 18 的行

AWK提供了一个内建的函数 length( $ arg) 用于返回字符串 $ arg 的总长度

如果要获取某行的总长度,可以使用下面的语法

length($0)

同样的,如果要获取某列/字段的总长度,可以使用语法 length( $ n)

如果要判断某行的字符是否大于/小于/等于 N ,可以使用下面的语法

length($0) > N

例如,如果要输出输出总长度大于 18 的行,可以使用下面的命令

[www.ddkk.com]$ awk 'length($0) > 18' employee.txt

因为所有的行的总长度都大于 18,因此输出结果如下

1)  张三  技术部  23
2)  李四  人力部  22
3)  王五  行政部  23
4)  赵六  技术部  24
5)  朱七  客服部  23

对于上面的输出,大家是不是很疑惑,length( $ 0) >18 只是一个条件语句,并没有输出语句 print($` 0) 为什么会输出每一行?

这是因为,AWK 中的条件语句,如果没有实际的条件执行代码,那么会有一个默认的执行代码,就是 print( $ 0),也就是输出当前行。