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.twle.cn]$ awk '{print $1 "\t" $3}' employee.txt
运行上面的代码,输出结果如下
1) 技术部 2) 人力部 3) 行政部 4) 技术部 5) 客服部
AWK 输出所有的行
我们前面有提到,AWK 的主体代码包括两大部分,模式和 AWK 语句
/pattern/ {awk-commands}
模式和语句都是可选的,但,必须存在其一。它们之间有几大规则
- 模式部分,是正则字符串匹配
- AWK 语句部分,是模式部分匹配成功后要执行的语句
- 如果模式部分省略,则默认每一行都匹配,也就是每一行都会被 AWK 语句执行
- 如果语句部分省略,那么默认的语句就是输出行,也就是
print $0
例如,下面的 awk 命令,用于输出行总包行 “术” 的行
[www.twle.cn]$ awk '/术/ {print $0}' employee.txt
运行上面的代码,输出结果如下
1) 张三 技术部 23 4) 赵六 技术部 24
因为 AWK 语句部分可以省略,因此,上面的命令可以参略为
[www.twle.cn]$ awk '/术/' employee.txt
运行上面的代码,输出结果如下
1) 张三 技术部 23 4) 赵六 技术部 24
AWk 输出匹配模式的某些列
需要注意的是,/pattern/
模式匹配是针对整行的,从某些方面说,是针对 $0
的。
我们还可以在行匹配模式之后,输出其中的某一列或者某几列。
例如,下面的命令,在行匹配之后,输出第二列和第三列,并且使用制表符分隔。
[www.twle.cn]$ awk '/术/ {print $1 "\t" $3}' employee.txt
运行上面的命令,输出结果如下
1) 技术部 4) 技术部
AWK 任意顺序输出列
因为 AWK 对每一列的分割在 BEGIN 语句执行完毕后就已经分割好了,因此我们在 AWK 主体代码中可以按照任意顺序把 $0....$n 传递给 print
函数
比如我们要想要先输出第三列,然后输出第一列,那么可以使用下面的命令
[www.twle.cn]$ awk '/术/ {print $3 "\t" $1}' employee.txt
运行上面的代码,输出结果如下
技术部 1) 技术部 4)
AWK 统计和输出满足模式的行
AWK 中的所有变量都不需要实现初始化,因为 AWK 发现它们如果没有初始化,则会自动初始化为 0
因此我们可以使用 {++count}
或者 {count++}
或者 {count = count+1}
来统计行数
[www.twle.cn]$ 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.twle.cn]$ 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)
,也就是输出当前行。