awk - 简介
awk指令的名称来自它的三位作者的姓名缩写:Alfred Aho, Peter Weinberger 和 Brian Kernighan。
它的主要行为就是:以行为单位进行分析、处理,特别适合处理文本格式的文件。
awk - 指令格式
$ awk 'pattern {action}' file
在单引号中的pattern和action,分别表示条件判断和执行的指令,file是待处理的文件。
当然,也可以使用管道的形式为awk指令提供处理数据,或者是来自用户的终端输入,就像sed指令中描述的那样。
pattern条件判断包括:
- == 相等
- != 不相等
- > 大于
- >= 大于或等于
- < 小于
- <= 小于后等于
- && 逻辑与
- || 逻辑或
另外,pattern还支持正则表达式。
action指令部分,最常用的就是print,用来输出相应的栏位。
awk内部提供了一些常用的内建变量,可以用来辅助输出一些有用的信息,常用的有:
- NR 读取到的行号;
- NF 当前处理行的栏位数(列数);
- FS 输入分隔符,默认:空格;
- OFS 输出分隔符,默认:空格;
- FILENAME 输入文件名
awk - 打印列
awk默认以空格来分隔一行内容,被分割的每一块内容以$n的变量形式表示,其中$0表示整行内容。
例如:打印文件中第1列和第3列
// 测试文件
$ cat test.txt
ZhangSan male 30 student
LiSi male 40
WangWu male 50 worker
$
$ awk '{print $1,$3}' test.txt
ZhangSan 30
LiSi 40
WangWu 50
为了让输出信息更直观,可以在指令中添加额外的字符串,例如:
$ awk '{print "col-1="$1," col-3="$3}' test.txt
col-1=ZhangSan col-3=30
col-1=LiSi col-3=40
col-1=WangWu col-3=50
示例:打印每一行的行号,以及该行有多少列
$ awk '{print "line="NR ", col=" NF "\t" $0}' test.txt
line=1, col=4 ZhangSan male 30 student
line=2, col=3 LiSi male 40
line=3, col=4 WangWu male 50 worker
示例:打印倒数第 1 列和倒数第 2 列
$ awk '{print $(NF-1) "===" $NF}' test.txt
30===student
male===40
50===worker
awk - BEGIN 和 END
[BEGIN] {初始化语句}
[{awk 命令}]
[END{最后执行的语句}]
以上这 3 部分内容不需要同时存在。
如果存在的话,BEGIN和END只会执行一次,用来做一些初始化(例如:设置分隔符)和统计信息(例如:统计处理了多少行)。
示例:设置输入分隔符,输出分隔符
// 测试文件
$ cat test2.txt
ZhangSan,male,30,student
LiSi,male,40
WangWu,male,50,worker
$
$ awk 'BEGIN{FS=",";OFS="==="} {print $1,$2} END{print "filename=" FILENAME ", rows="NR}' test2.txt
ZhangSan===male
LiSi===male
WangWu===male
filename=test2.txt, rows=3
awk - 对内容进行过滤
示例:打印第一列等于ZhangSan的那些行
$ awk '$1 == "ZhangSan" {print $0}' test.txt
ZhangSan male 30 student
示例:打印行内容中包含 ang 的信息(正则表达式)
$ awk '/ang/ {print $0}' test.txt
ZhangSan male 30 student
WangWu male 50 worker
示例:打印行内人中以 W 开头的信息(正则表达式)
- ^ 匹配开头字符
- $ 匹配结束字符
$ awk '/^W/ {print $0}' test.txt
WangWu male 50 worker
示例:打印行内容中包含Zhang或者Wang的信息
- [] 匹配方括号中的任意字符
$ awk '/[Zh|W]ang/ {print $0}' test.txt
ZhangSan male 30 student
WangWu male 50 worker
示例:打印行内容中不包含Zhang和Wang的信息
$ awk '!/[Zh|W]ang/ {print $0}' test.txt
LiSi male 40
示例:打印年龄小于45的信息
$ awk '$3<45 {print $0}' test.txt
ZhangSan male 30 student
LiSi male 40
示例:打印第4列不为空的信息
$ awk 'NF==4 {print $0}' test.txt
ZhangSan male 30 student
WangWu male 50 worker
awk - 格式化输出
格式化控制字符与 C 语言中的相同。
示例:格式化打印姓名和年龄
$ awk '{printf ("%10s %03d \n", $1, $3)}' test.txt
ZhangSan 030
LiSi 040
WangWu 050

Linux 茶馆
