正文
1、基本介绍
awk 是一个处理文本文件的实用工具,常规的命令格式如下:
> awk [options...] 'BEGIN{statements} condition {actions} END{statements}' <file>
多个 statement
或多个 action
之间用 ;
分开,整个命令的作用过程如下:
- 首先执行 BEGIN 块中的 statements,BEGIN 块中的 statements 只会在开始前执行一次
- 然后按行遍历 file,如果该行满足 condition,那么对其执行 actions
- 最后执行 END 块中的 statements,END 块中的 statements 只会在结束后执行一次
2、基本使用
首先我们构造一个测试文件 data.txt
,它的内容如下:
this is the 1st line this is the 2nd line this is the 3rd line this is the 4th line this is the 5th line
(1)actions
常见的 actions 一般是 print
,print
命令会打印在其后面指定的内容
> awk '{ print $0 }' data.txt # this is the 1st line # this is the 2nd line # this is the 3rd line # this is the 4th line # this is the 5th line
上面的命令会打印每一行的 $0,$0 是一个特殊的标志,表示当前行的内容
此外,awk 还会使用分隔符将每一行分成若干字段,$1 表示第 1 个字段,$2 表示第 2 个字段,以此类推
默认的分隔符是空格和制表符,我们还可以使用 -F
参数自己指定分隔符
> awk -F 'the' '{ print $2 }' data.txt # 1st line # 2nd line # 3rd line # 4th line # 5th line
(2)内置变量
awk 中有一些内置的变量供我们使用,常见的变量包括:
变量 | 含义 |
NR |
当前记录的行号 |
NF |
当前记录的字段个数 |
RS |
记录分隔符,默认是 换行符 |
FS |
字段分隔符,默认是 空格和制表符 |
ORS |
输出的记录分隔符,默认是 换行符 |
OFS |
输出的字段分隔符,默认是 空格 |
我们来看一个例子,该例子展示的是 NR
参数的使用,这里的结果很直观,不多作解释
> awk '{ print NR }' data.txt # 1 # 2 # 3 # 4 # 5
大家能不能解释一下,下面的这个命令为什么会输出这样的结果呢
> awk '{ print $NR }' data.txt # this # is # the # 4th # line
其实也很简单,对于第 1 行来说,NR
等于 1,所以 $NR
表示的是第 1 个字段,因此输出的是 this
对于第 2 行来说,NR
等于 2,所以 $NR
表示的是第 2 个字段,因此输出的是 is
,下面以此类推
(3)内置函数
awk 还有一些内置的函数,常见的函数包括:
函数 | 含义 |
toupper() |
将字符转换为大写 |
tolower() |
将字符转换为小写 |
length() |
返回字符串的长度 |
substr() |
返回子字符串 |
我们还是来看一个例子,该例子展示的是 substr
函数的使用
> awk '{ print substr($0, 13) }' data.txt # 1st line # 2nd line # 3rd line # 4th line # 5th line
(4)condition
- 既可以是 条件语句
> # 只处理 NR >= 1 && NR <= 3 的记录 > awk 'NR >= 1 && NR <= 3 { print $0 }' data.txt # this is the 1st line # this is the 2nd line # this is the 3rd line
- 也可以是 正则表达式
> # 只处理 $0 能匹配正则 /[0-9]th/ 的记录 > awk '$0 ~ /[0-9]th/ { print $0 }' data.txt # this is the 4th line # this is the 5th line > # 只处理 $4 能匹配正则 /^[0-9]th$/ 的记录 > awk '$4 ~ /^[0-9]th$/ { print $4 }' data.txt # 4th # 5th
(5)BEGIN 和 END
> # 统计行数 > awk 'BEGIN{ count = 0 } { count += 1 } END{ print count }' data.txt # 5