介绍

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理,切开的部分使用awk可以定义变量、运算符,使用流程控制语句进行深度加工与分析。

创始人 Alfred V. Aho、Peter J. Weinberger和Brian W. Kernighan awk由来是姓氏的首字母。

语法

1
awk [options] 'pattern{action}' {filenames}
  • pattern:表示awk在数据中查找的内容,就是匹配模式
  • action:在找到匹配内容时所执行的一系列命令

选项参数说明:

选项参数 功能
-F 指定输入文件拆分分隔符
-v 赋值一个用户定义变量

awk内置变量

内置变量 含义
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数, 根据分隔符分割后的列数
NR 已读的记录数, 也是行号
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
$n $0变量是指整条记录。$1表示当前行的第一个域,$2表示当前行的第二个域,……以此类推。
$NF $NF是number finally,表示最后一列的信息,跟变量NF是有区别的,变量NF统计的是每行列的总数

演示

数据准备:将linux用户配置文件拷贝到当前目录

1
cp /etc/passwd ./

1.默认每行空格切割数据

1
echo "abc 123 456" | awk '{print $1"&"$2"&"$3}'

运行效果

2.打印含有匹配信息的行

搜索passwd文件有root关键字的所有行:

1
2
awk '/root/' passwd
# '/root/' 是查找匹配模式, 没有action命令, 默认输出所有符合的行数据

运行效果

3.打印匹配行中第7列数据

搜索passwd文件有root关键字的所有行,然后以”:”拆分并打印输出第7列:

1
2
awk -F: '/root/{print $7}' passwd
# -F: 以':'分隔符拆分每一个列(域)数据

运行效果

4.打印文件每行属性信息

统计passwd:文件名,每行的行号,每行的列数,对应的完整行内容:

1
2
awk -F ':' '{print "文件名:" FILENAME ",行号:" NR ",列数:" NF ",内容:" $0}' passwd
# "文件名:" 用于拼接字符串

运行效果

使用printf替代print,可以让代码阅读性更好:

1
2
3
4
5
awk -F ':' '{printf("文件名:%5s,行号:%2s, 列数:%1s, 内容:%2s\n",FILENAME,NR,NF,$O)}' passwd
# printf(格式字符串,变量1,变量2,...)
# 格式字符串: %ns 输出字符串,n 是数字,指代输出几个字符, n不指定自动占长度
# 格式字符串: %ni 输出整数,n 是数字,指代输出几个数字
# 格式字符串: %m.nf 输出浮点数,m 和 n 是数字,指代输出的整数位数和小数位数。如 %8.2f 代表共输出 8 位数,其中 2 位是小数,6 位是整数;

运行效果

5.打印第二行信息

打印passwd的第二行信息:

1
awk -F ':' 'NR==2{printf("filename:%s,%s\n",FILENAME,$0)}' passwd

运行效果

6.查找以c开头的资源

awk过滤的使用,查找当前目录下文件名以c开头的文件列表:

1
ls -a | awk '/^c/'

运行效果

7.打印第一列

按照”:” 分割查询第一列打印输出:

1
awk -F ':' '{print $1}' passwd

运行效果

8.打印最后一列

按照”:” 分割查询最后一列打印输出:

1
awk -F: '{print $NF}' passwd

运行效果

9.打印倒数第二列

按照”:” 分割查询倒数第二列打印输出:

1
2
awk -F: '{print $(NF-1)}' passwd
# $(NF-N) N是几, 就是倒数第几列

运行效果

10.打印10到20行的第一列

获取第10到20行的第一列的信息:

1
awk -F: '{if(NR>=10 && NR<=20) print $1}' passwd

运行效果

11.多分隔符使用

“one:two/three”字符串按照多个分隔符”:”或者”/“ 分割,并打印分割后每个列数据:

1
echo "one:two/three" | awk -F '[:/]' '{printf("%s\n%s\n%s\n%s\n",$0,$1,$2,$3)}'

运行效果

12.添加开始与结束内容

给数据添加开始与结束:

1
2
echo -e  "abc\nabc" | awk 'BEGIN{print "开始..."} {print $0} END{print "结束..."}'
# BEGIN 在所有数据读取行之前执行;END 在所有数据执行之后执行。

运行效果

13.使用循环拼接分割后的字符串

“abc itheima itcast 21” 使用空格分割后,通过循环拼接在一起:

1
2
echo "abc itheima     itcast   21" | awk -v str="" -F '[ ]+' '{for(n=1;n<=NF;n++){ str=str$n} print str }'
# -v 定义变量

运行效果

14.操作指定数字运算

将“2.1”增加数值1并输出:

1
echo "2.1" | awk -v i=1 '{print $0+i}'

运行效果

15.切割ip

1
ifconfig | awk '/broadcast/{print}' | awk -F " " '{print $2}'

运行效果

16.显示空行行号

查询sed.txt中空行所在的行号:

1
sed 'G' sed.txt | awk '/^$/{print NR}'

运行效果