1. 简介
awk是一个强大的文本分析工具 ,和大家经常使用的grep、sed 并称linux文本处理三大神器,相较于grep、sed来说awk更加强大,强大到几乎可以实现另外两位的大部分功能,强大到拥有自己的编程语言,甚至于可以创建简短的程序,来实现数据排序,处理数据,执行计算,生成报表等等无数其他的功能。
2. 命令格式
awk 操作符 ' 模式 { awk语法指定的操作 }' 数据文件
管道数据 | awk 操作符 ' 模式 { awk语法指定的操作 }'
awk的命令可简单分为4部分
awk : 命令关键字 必填
操作符 : 可用于指定域分隔符 , 可用于指定变量复制等等(选填)
' 模式 { awk执行的操作 } '
单引号对 : 不可省略 , 但是其中的内容可为空
模式 : 可以简单理解编程语言中的判别式 , 区别是模式表达式可省略if , 当匹配时,执行后面的awk操作(可省略 , 默认为 匹配)
awk语法指定的操作 : awk通过一些简单的语法进行操作的指定 , 并且只有大括号内的内容 , 可被awk通过语法进行解析执行, 语法间通过 ' ; ' 进行分隔(可省略)
数据来源 : awk支持处理两种数据源 , 第一种: 文件数据 第二种: 管道数据
3. 运行逻辑
awk命令的运行逻辑大致如下图所示
举个例子
前面的概念和流程图可能过于抽象 , 下面我们通过几个简单的实例帮助下理解消化.
最简单的awk命令: 因为没有指定动作 ,所以什么都不做.
按行读取(默认按换行分隔), 输出每一行的内容 , $0 代表当前行
按行读取 , 默认空格将每行分隔成列 , 输出每行第1列的值 , 具体如何分隔取值后面会讲到
4. 常用选项与关键字
列的取值关键字: 比如 aa bb cc dd这行数据 , 默认按空格分隔成列后 , $0 : 代表整行数据 , 后面依次递增 例如 $1 : aa $2:bb $3:cc $4:dd
NR: 行号 , NF:列数 举例: 输出第一行的 倒数第二列 和 最后一列 使用 ' ! ' 进行分隔显示
RS : 行分隔符 , 举例: 指定 ' : ' 进行行的分隔 , 输出每一行的数据
-F 指定列分隔符 , FS: 列分隔符
举例1: 指定':' 为列分隔符 , 并输出列数和列分隔符
举例2: 指定多个列分隔符 (双引号内符合正则匹配的规则), 并输出列数
BEGIN 和 END : 我们从流程图可以看到 BEGIN 和 END 可以理解为开始循环读取前 和 结束循环读取后的两个时间点 举例: 在开始前设置列分隔符 , 结束时输出指定语句
5. 模式匹配
注意当模式匹配为空时 , 则默认为所有行都匹配成功
正则表达式 , 做模式匹配 ,
/正则表达式/
举例: 匹配以a开头的行
关系表达式 , 做模式匹配 , 举例当行号=1时 , 输出整行
6. awk基础语法操作
变量赋值 , awk支持数字 , 字符串 , 甚至是一维数组 , 关联数组(类似于Map的结构)
# 命令格式echo "aabb" | awk '{ a=1;print "普通数字赋值"a}{b["key1"]=1;b["key2"]=2;for(arg in b){print arg}}'# 拆解后 , awk的语言其实就和平时常见的编程语言类似echo "aabb" | awk' { a=1; print "普通数字赋值"a } { b["key1"]=1; b["key2"]=2; for(arg in b) { print arg } } '
运算符
# 比较运算符< <= > >= == !=# 支持赋值运算符= += -= *= /= %= ^=# 三元运算符?:# 常规运算符+ - * / %# 逻辑运算符&& || !# 加加与减减++ --# 匹配正则表达式和不匹配正则表达式~ !~# 变量引用$# 数组成员in
if语句
# 基础格式if(condition1) {statements1;...} else if(condition2) {statements2;...} else {statements3;...}# 实例awk '{ if(NR=1){print $0}else if(NR=2){print $0}else{print $0}}' test.txt
awk内置的常用函数
# 字符转为小写tolower()# 转化为大写toupper()# 返回字符串长度length()# 返回字符串长度substr()# 字符串截取substr(str,num1,num2)# 返回第一次匹配到的下标index(segmentStr,originStr)# 平方根sqrt()# 随机数rand()
常用操作 , 最后放上一些基础的操作 , 大家可以模仿着 , 实现自己的需求
# 打印第一列awk '{print $1}' test.txt# 格式化打印第一列第二列awk '{print $1,\t,$2}' test.txt# 打印第一行awk 'NR==1 {print $0}' test.txt# 打印匹配到数字的行的行号和第一列awk '/[0-9]/ {print NF,$1}' test.txt# 打印第一列匹配到数字的行awk '$1~/[0-9]/ {print $0}' test.txt# 不匹配数字的行awk '!/[0-9]/ {print $0}' test.txt# 设置 : 为分隔符awk -F ':' '{print $1}' test.logawk 'BEGIN{FS==":"} {print $1}' test.txt# 多重分割,用空格和逗号做分给,逻辑上是先用空格分隔,之后空格里在用逗号分隔awk -F '[ ,]' '{print $1,$2}' test.txt# 不区分大小写匹配awk 'BEGIN{IGNORECASE=1} /aaa/' test.txt# 输出 0-1 的随机数echo | awk '{srand(); print rand()}'
![7e2431e52db587ff8c52663f83b54eed.gif](https://i-blog.csdnimg.cn/blog_migrate/6ce21a948509bc5875d22deeb428657d.gif)
![df825952d94ae0983423c7697207abf3.gif](https://i-blog.csdnimg.cn/blog_migrate/8e912ea73da851c1671e7240eb7f1661.gif)
![0c3710b13260bdbe50f40d3350a2879b.gif](https://i-blog.csdnimg.cn/blog_migrate/b3b2da60833eab2f2ccfed1f32fee657.gif)