AWK 命令
awk 是文本处理工具。
awk 命令接收的参数分为四个部分:
- 选项
- 脚本代码
- 变量
- 待处理文件
大多数 awk 命令只用到选项、脚本代码、待处理文件。
示例文本
test.txt
|
|
选项
最常用的选项是 -F field-separator
,用来选择以什么字符串作为分割字段的依据。例如 -F ','
表示按照 ,
分割行。
另一个常用选项是 -f script-file
,用来选择分析脚本文件。如果脚本代码太多,不适合写在命令参数里面,选择写在文件里面,则使用这个参数加载脚本。
脚本代码
如果没有使用 -f script-file
参数,则需要在命令参数里写脚本代码。
脚本代码由单引号括起来,例如 '{print $1}'
。这是因为在 shell 里写命令时,$
符号用来表示使用一个变量。如果用双引号,则会被解释为使用某个变量。如果用单引号,则不会被解释,而是原样传入 awk 命令。
脚本代码使用 $数字
的方式表示第几个字段,例如 $1
表示分割后的第一个字段。
脚本代码由模式+动作组成,动作的代码由花括号包裹,组合起来的为pattern{action}
。可以有多个这样的组合,组合之间不需要间隔符(可自己加空格便于阅读),每个组合都会对一行分别执行一次。满足模式的时候,就会执行相应的动作。
例如:
|
|
结果是:
|
|
模式可以省略,表示对于每行都执行动作。
例如:
|
|
结果是:
|
|
模式有很多种,常用的有:
- BEGIN
- END
- 条件表达式
- 正则表达式
BEGIN 表示读取文件之前,通常用于初始化变量。END 表示不再读取文件之后,通常用于打印最终的结果。
例如:
|
|
结果是:
|
|
内建变量
有时候会对处理的行数有要求,例如前面的结果中把第一行也打印出来了,如果要把某一行去掉,可以自己声明一个变量记录行数:
|
|
结果:
|
|
每次都这样写麻烦,因此 awk 内置了一个变量 NR
用于表示当前行数。awk 默认把每行看作一条记录,NR 是 Number of records 的缩写。
于是上面的命令就简化为:
|
|
awk 默认把每行看作一条记录,是因为其记录分隔符被默认为换行符 \n
。可以通过给内置变量 RS
(Record separator)赋值改变记录分隔符。
例如:
|
|
结果是:
|
|
这里的 “xiaoming” 和 “xiaohong” 丢失是因为每次按照 ,
分割,得到的是 age\nxiaoming
这样的结果。然后默认的 FS
(Field separator),也就是 -F
参数,是空白字符。空白字符包括空格和换行,因此 $1
就只包含 age。
如果要展示完整,则使用 $0
。它表示一个 record 里的所有 field。
|
|
结果是:
|
|
如果一行中间的字段数不同,但要打印最后一个字段呢?
有一个内置变量表示当前 Record 的字段数,NF
(Number of field)。
|
|
结果是:
|
|
同理,倒数第二个字段为:
|
|
计算五分钟带宽
|
|