0,简介

Linux awk 是一个实用的文本处理工具,它不仅是一款工具软件,也是一门编程语言awk 的名称来源于其三位作者的姓氏缩写,其作者分别是Alfred AhoPeter WeinbergerBrian Kernighan

如果你在linux 系统中追踪awk,可以看到其最终指向的是/usr/bin/gawk,也就是gawk 命令。其GNU官方手册 权威且全面,但对于初学者并不是很友好,因为内容非常多,你可能不知从何看起。对于普通用户,一般也用不到非常复杂的功能。

如果一个文件由规则的多个列组成,则非常适合使用awk 来处理。本文介绍awk 常用方法,对于普通使用者应该是足够了。

1,基本概念

awk 命令会对文本文件每一行进行处理,其语法格式如下:

awk `参数` `pattern {action}` `filename`

pattern 是要匹配的规则,action 是要执行的动作,只有匹配了pattern,才会执行动作action

这句命令的含义是:对于文件filename 的每一行,如果能够符合条件pattern,则执行动作action。如果不写pattern,则表示对于文件filename的每一行,都进行action 处理。

1.1,参数

awk 最常使用的参数是-F,其后跟一个分隔符或者正则表达式,其表示的意思是以怎样的规则对每一行进行分割。 默认是空格Tab键

1.2,pattern

pattern 可以是下表中的任意一项:

pattern 说明
/正则表达式/ 正则写在两个/ 之间
关系表达式 awk 中支持的关系运算符组成
模式匹配表达式 ~(匹配)和!~(不匹配)组成
BEGIN{语句} 在处理第一行文本之前,执行BEGIN 块中的语句,可以在这里进行一些变量初始化等操作
END{语句} 在处理完最后一行文本之后,执行END 块中的语句
/规则1/,/规则2/ 这是一个范围模板,只处理规则1第一次出现与规则2第一次出现之间的行

1.3,action

actionawk 语句组成,比如print,用于输出。

2,awk 内置变量

awk 中内置了很多变量,来方便使用,这里介绍一些常用的:

awk 内置变量 含义
FS 表示分隔符,类似-F 参数的功能
$0 一行的完整内容
$n 分隔符隔开的第n列,比如$1 表示第一列
FILENAME 当前文件名
NR 当前行数,即当前行是第几行
NF 当前行的列数,即当前行分割符分成了几列
IGNORECASE 如果为真,表示忽略大小写进行匹配

3,awk 内建函数

awk 常用函数如下:

函数 含义
tolower() 字符串转小写
toupper() 字符串转大写
length() 计算字符串长度
split() 字符串分割
systime() Unix 时间戳
strftime() 时间格式化,用法同C语言中的strftime 函数
rand() 随机数
sin() 正弦
cos() 余弦
sqrt() 平方根
exp() 求幂

4,awk 运算符

awk 支持如下常用运算符

运算符 含义
+ - * / & 加,减,乘,除,求余
= += -= *= /= %= ^= **= 赋值运算符
< <= > >= != == 比较运算符
空格 用于连接字符串,使用较多
|| 逻辑
&& 逻辑
! 逻辑
~ 匹配
!~ 不匹配

5,awk 使用案例

假如,我们有如下文件,分别为姓名性别年龄成绩等级省份

>>> cat log.txt
_________________
小明,男,23,550^优秀---北京
小丽,女,22,560^优秀---河北
小磊,男,24,530^良好---河南
小召,男,23,540^优良---山东
小欣,女,23,545^优良---山西

5.1 使用-F

以逗号,分隔符,并将第1列,第2列和第3列输出,如下:

>>> awk -F, '{print $1,$2,$3}' log.txt
______________________________________
小明 男 23
小丽 女 22
小磊 男 24
小召 男 23
小欣 女 23

分隔符只有一个字符时,分割符可以紧挨-F,还有如下几种写法:

awk -F , '{print $1,$2,$3}' log.txt		#`分隔符`与`-F`之间有一个空格
awk -F',' '{print $1,$2,$3}' log.txt #`分隔符`用单引号引住,并且紧挨`-F`
awk -F"," '{print $1,$2,$3}' log.txt #`分隔符`用双引号引住,并且紧挨`-F`
awk -F ',' '{print $1,$2,$3}' log.txt #`分隔符`用单引号引住,与`-F`之间有空格
awk -F "," '{print $1,$2,$3}' log.txt #`分隔符`用双引号引住,与`-F`之间有空格

分隔符多个连续字符时,必须用双引号或者单引号引住分割符,可以紧挨-F,也可以有空格

awk -F '---' '{print $2}' log.txt	#`分隔符`用单引号引住,与`-F`之间有空格
awk -F"---" '{print $5}' log.txt #`分隔符`用双引号引住,与`-F`之间没有空格

以上两个命令输出的内容一样,此时分隔符---,每一行都被分成了两列,如下:

小明,男,23,550^优秀 北京
小丽,女,22,560^优秀 河北
小磊,男,24,530^良好 河南
小召,男,23,540^优良 山东
小欣,女,23,545^优良 山西

当有多个单独的分割符时,将多个分隔符写在中括号[]中,如下,表示以, 或者以--- 为分隔符:

>>> awk -F "[,^]" '{print $1, $2, $3, $4, $5}' log.txt
________________________
小明 男 23 550 优秀---北京
小丽 女 22 560 优秀---河北
小磊 男 24 530 良好---河南
小召 男 23 540 优良---山东
小欣 女 23 545 优良---山西

5.2 使用内置变量

我们用变量NR输出当前行号,变量NF输出当前行的列数,变量FILENAME输出当前文件名,如下:

>>> awk -F"---" '{print NR, $1, $2, NF, FILENAME}' log.txt
__________________________________________________________
1 小明,男,23,550^优秀 北京 2 log.txt
2 小丽,女,22,560^优秀 河北 2 log.txt
3 小磊,男,24,530^良好 河南 2 log.txt
4 小召,男,23,540^优良 山东 2 log.txt
5 小欣,女,23,545^优良 山西 2 log.txt

5.3 如何连接字符串

我们将每一列使用竖线| 分割,方法是将分隔符双引号引住,然后紧挨变量,如下:

>>> awk -F"---" '{print NR"|"$1"|"$2"|"NF"|"FILENAME}' log.txt
__________________________________
1|小明,男,23,550^优秀|北京|2|log.txt
2|小丽,女,22,560^优秀|河北|2|log.txt
3|小磊,男,24,530^良好|河南|2|log.txt
4|小召,男,23,540^优良|山东|2|log.txt
5|小欣,女,23,545^优良|山西|2|log.txt

5.3 使用内置函数

使用内置函数systime() 输出时间戳,如下:

>>> awk -F"---" '{print NR"|"$1"|"$2"|"NF"|"FILENAME"|"systime()}' log.txt
—————————————————————————————————————————————
1|小明,男,23,550^优秀|北京|2|log.txt|1587022443
2|小丽,女,22,560^优秀|河北|2|log.txt|1587022443
3|小磊,男,24,530^良好|河南|2|log.txt|1587022443
4|小召,男,23,540^优良|山东|2|log.txt|1587022443
5|小欣,女,23,545^优良|山西|2|log.txt|1587022443

使用length 输出行长度大于5 的行:

>>> awk 'length>5' log.txt
——————————————————————————
小明,男,23,550^优秀---北京
小丽,女,22,560^优秀---河北
小磊,男,24,530^良好---河南
小召,男,23,540^优良---山东
小欣,女,23,545^优良---山西

5.4 使用pattern

使用pattern 只输出 同学信息,$0 表示每一行的原始内容,如下:

>>> awk '/男/ {print NR"|"$0}' log.txt
__________________________
1|小明,男,23,550^优秀---北京
3|小磊,男,24,530^良好---河南
4|小召,男,23,540^优良---山东

5.5 使用逻辑非!

使用逻辑非!,输出不为的学生信息:

>>> awk '!/男/ {print NR"|"$0}' log.txt
__________________________
2|小丽,女,22,560^优秀---河北
5|小欣,女,23,545^优良---山西

5.6 使用关系表达式

使用关系表达式,输出年龄为23 的学生信息:

# 以逗号分割后的第三列为年龄
>>> awk -F, '$3==23 {print $3, $0}' log.txt
____________________________
23 小明,男,23,550^优秀---北京
23 小召,男,23,540^优良---山东
23 小欣,女,23,545^优良---山西

也可以写成如下方式,输出年龄为23或25 的学生信息:

>>> awk -F, '$3==23 || $3==25' log.txt
________________________
小明,男,23,550^优秀---北京
小召,男,23,540^优良---山东
小欣,女,23,545^优良---山西

5.7 使用模式匹配表达式

使用模式匹配表达式,输出年龄为24 的学生信息:

awk -F, '$3 ~/24/ {print $3, $0}' log.txt
24 小磊,男,24,530^良好---河南

5.8 使用if 语句

awk 也支持if 语句,输出年龄为22 的学生信息,if 语句写在大括号{}内:

>>> awk -F, '{if($3==22) print $3, $0}' log.txt
___________________________
22 小丽,女,22,560^优秀---河北

5.9 使用NR 输出基数行

# `NR % 2 == 1` 为基数行
>>> awk -F, 'NR % 2 == 1 {print NR, $0}' log.txt
——————————————————————————
1 小明,男,23,550^优秀---北京
3 小磊,男,24,530^良好---河南
5 小欣,女,23,545^优良---山西

5.10 使用NF 输出倒数第一列

$(NF) 为倒数第1列,$(NF-1) 为倒数第2列,$(NF-2) 为倒数第3列,依次类推。

如下输出倒数第1列:

>>> awk -F, '{print $(NF)}' log.txt
______________
550^优秀---北京
560^优秀---河北
530^良好---河南
540^优良---山东
545^优良---山西

5.11 使用BEGIN 块

BEGIN 块中可以是任意多个合法的awk 语句

>>> awk -F, 'BEGIN{print "姓名", "性别", "年龄"} {print $1, $2, $3}' log.txt
____________
姓名 性别 年龄
小明 男 23
小丽 女 22
小磊 男 24
小召 男 23
小欣 女 23

5.12 使用END 块

END 块中可以是任意多个合法的awk 语句BEGIN 块END 块可以一起使用。

>>> awk -F, 'BEGIN{print "姓名", "性别", "年龄"} {print $1, $2, $3} END{print "共有"NR"行信息"}' log.txt
____________
姓名 性别 年龄
小明 男 23
小丽 女 22
小磊 男 24
小召 男 23
小欣 女 23
共有5行信息

5.13 使用范围模板

输出小丽和小欣之间的行数据:

>>> awk '/小丽/,/小欣/' log.txt
______________________________
小丽,女,22,560^优秀---河北
小磊,男,24,530^良好---河南
小召,男,23,540^优良---山东
小欣,女,23,545^优良---山西

(完。)

最新文章

  1. javascript读取xml文件
  2. python学习道路(day5note)(列表生成式,生成器,装饰器,常用模块)
  3. Xcode6如何自己添加pch文件?
  4. Excel 读取字符串引发的问题
  5. WIn2003的IIS6解决IE11登录问题。
  6. 扩展欧几里德解的数量(51nod 1352)
  7. OGNL表达式介绍
  8. xamarin SimpleAdapter绑定出错问题
  9. (转)在.net中序列化读写xml方法的总结
  10. winform自动更新并实现文件的批量异步下载
  11. 记一次Spring aop的所遇到的问题
  12. jacascript DOM节点——节点关系与操作
  13. BZOJ_2068_[Poi2004]SZP_树形DP
  14. 智能指针std::weak_ptr
  15. FTP主动及被动模式效果图
  16. vue菜鸟从业记:公司项目里如何进行前后端接口联调
  17. webpack4 系列教程(七): SCSS提取和懒加载
  18. Flask最强攻略 - 跟DragonFire学Flask - 第八篇 实例化Flask的参数 及 对app的配置
  19. Angular 学习笔记 ( timezone + moment + material date-picker + date pipe + asp.net core )
  20. 第八天- 基础数据操作补充 集合set 深浅拷贝

热门文章

  1. 2019ICPC(银川) - Delivery Route(强连通分量 + 拓扑排序 + dijkstra)
  2. k8s + docker + Jenkins使用Pipeline部署SpringBoot项目时Jenkins错误集锦
  3. Promise入门详解
  4. Java并发基础04. 线程技术之死锁问题
  5. 查看手机wifi密码
  6. python 函数简介
  7. Android Google Play app signing 最终完美解决方式
  8. pgsql中的事务隔离
  9. [算法]Huffman树(哈夫曼树)
  10. Sentry实时应用错误跟踪系统在Kubernetes中私有化部署