三剑客之-awk
目录
1.4.2、按单词出现频率降序排序(计算文件中每个单词的重复数量)
2.6.1、第二个作用,在读取文件之前输出写提示性信息,表头
2.6.2、第三种用法,使用BEGIN模块的特殊性质进行测试
2.6.5、统计/etc/services文件里面的空行数量
一、awk简介与使用
1.1、awk讲解
awk是一种编程语言,用于在linux/unix下对文本和数据进行处理,能够对文本进行复杂的格式处理,是一种处理文本的语言,可以进行样式装入、流控制、数学运算、流程控制,还有内置的变量和函数,具备一个完整语言所应具有的几乎所有完美特性,相当于一个小型编程语言。其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。
1.1、查看awk版本
1.2、awk的格式
awk指令是由模式,动作,或者模式和动作的组合组成,
模式即pattern,可以类似理解成sed的模式匹配,可以有表达式组成,也可以是两个正斜杠之间的正则表达式。比如NR==1,这就是模式,可以把它理解为一个条件。
动作即action,是由在大括号里面的一条或多条语句组成,语句之间使用分号隔开。如下awk使用格式:
awk处理的内容可以来自标准输入(<)一个或多个文本文件或管道
pattern即模式,可以理解为条件,以什么条件为例去找?都是条件即模式
action即动作,可以理解为干啥,找到之后要做什么。
1.3、awk执行过程
1.4、记录和字段
下面是两个新概念的记录和字段,为了方便理解可以把记录就当做行即记录==行,字段相当于列,字段==列。
名称 |
含义 |
record |
记录,行 |
field |
域,区域,字段,列 |
创建测试环境:
1.4.1、记录(行)
awk对每个要处理的输入数据认为都是具有格式和结构的,而不仅仅是一堆字符串。默认情况下,每一行内容都是一条记录,并以换行符(\n)结束。
(1)awk记录分隔符-RS
记录分隔符-每一个记录(行)是如何结束的
- awk默认情况下每一行都是一个记录(record)
- RS即record separator输入数据记录分隔符,每一行是怎么没的,表示每个记录输入的时候的分隔符,即行与行之间如何分隔。
- NR即number of record记录(行)号,表示当前正在处理的记录(行)的号码
- ORS即output record separate输出记录分隔符
awk使用内置变量RS来存放输入记录分隔符,RS表示的是输入的记录分隔符,这个值可以通过BEGIN模块重新定义修改
在awk眼中,文件是从头到尾一段连续的字符串,恰巧中间有些(\n回车换行符),\n也是字符。
\n就是换行,所以后面的内容到了下一行
(2)对$0的认识
如上图可看出awk中$0表是整行,其实awk使用$0来表示整条记录。记录分隔符\n保存在RS变量中。
另外awk对每一行的记录号都有一个内置变量NR来保存,每处理完一条记录NR的值就会自动+1 。
1.4.2、按单词出现频率降序排序(计算文件中每个单词的重复数量)
注:(此处使用sort与uniq即可)
思路:
- 让所有单词排成一列,这样每个单词都会是单独的一行
- 设置RS值为空格
- 将文件里面的所有空格替换为回车换行符“\n”
整体思路:想办法让所有单词排成一列,站成一排,排序,合并重复的,显示重复数量
sort :默认是按照 字母顺序排列
-r :倒序
-n :按数字排序
uniq :把重复的合并成一行
-c:显示重复出现的次数
一步一步来,先修改了RS,然后用NR调试,看看到底如何分隔的。
然后通过sort排序,uniq去重。
1.4.3、awk记录小结
- NR存放着每个记录的号(行号)读取新行时会自动+1
- RS是输入数据的记录的分隔符,简单理解就是可以指定每个记录的结尾标志
- RS作用就是小事一个记录的结束
- 当我们修改了RS的值,最好配合NR(行)来查看变化,也就是修改了RS的值通过NR查看结果,调试awk程序
- ORS输出数据的记录的分隔符
1.4.4、字段(列)
每条记录都是由多个区域(field)组成的,默认情况下区域之间的分隔符是由空格(即空格或制表符)来分隔,并且将分隔符记录在内置变量FS中,每行记录的区域保存在awk的内置变量NF中。
约定:
field有很多种解释,域,记录,区域。为了方便理解适用区域表示(field)
FS即field separator 输入字段(列)分隔符。把一行字符串切为很多个区域。
NF即number of fileds,表示一行中列(字段)的个数,可以理解为切成了多少份。
OFS使用内置变量FS来记录区域分隔符的内容,FS可以在命令行上通过-F参数来更改,也可以通过BEGIN模块来更改
然后通过$n,n是整数,来取被切割后的区域,$1取第一个区域,$2取第二个区域,$NF取最后一个区域。
实例:
在动作('{print $3,$NF}')中的逗号,表示空格,其实动作中的逗号就是OFS的值,刚开始吧逗号当作空格即可
1.4.5、ORS与OFS简介
现在说说ORS和OFS这两个内置变量的含义
RS是输入记录分隔符,决定awk如何读取或分隔每行(记录)
ORS表示输出记录分隔符(output record separator),决定awk如何输出一行(记录)的,默认是回车换行(\n)
FS是输入区域分隔符,决定awk读入一行后如何再分为多个区域
OFS表示输出区域分隔符,决定awk输出每个区域的时候是用什么分隔他们
awk无比强大,可以通过RS,FS决定awk如何读取数据。也可以通过修改ORS,OFS的值指定awk如何输出数据。
例:
调换/etc/passwd中第一列和最后一列位置
FS与OFS
这里只是指定了FS和修改OFS,让输出分隔符。
上面的命令也可以写成
RS与ORS
(1)RS记录分隔符,表示每行的结束标志
(2)NR行号(记录号)
(3)FS字段分隔符,每列的分割标志或结束标志
(4)NF就是每行有多少列,每个记录中字段的数量
小结:
1) $符号表示取某个列(字段),$1,$2,$NF
2) NF表示记录中的区域(列)数量,$NF取最后一个列(区域)
3) FS(-F)字段(列)分隔符 -F(FS) ":" <==> 'BEGIN{FS=";"}'
4) RS 记录分隔符(行的结束标识)
5) NR行号
6) 选好合适的方式FS(***),RS,OFS,ORS
7) 分隔符==>结束标识
8) 记录与区域,就对我们所谓的行与列,有了新的认识(RS,FS)
二、awk进阶
2.1、awk模式与动作
awk的格式,里面的模式动作,换句话说就是条件和做什么
2.2、正则表达式作为模式
awk同sed一样可以通过模式匹配来对输入的文本进行匹配处理。模式匹配肯定少不了正则表达式,awk也支持大量的正则表达式模式,大部分与sed支持的元字符类似,而且正则表达式是玩转三剑客的必备工具
下面表格列出了awk支持的正则表达式元字符:
元字符 |
功能 |
示例 |
解释 |
^ |
字符串开头 |
/^xty/ $3~/^xty/ |
匹配所有以xty开头的字符串 匹配出所有第三列中以xty开头 |
$ |
字符串结尾 |
/xty$/ $3~/xty$/ |
匹配所有以xty结尾的(字符串) 匹配第三列中以xty结尾的文本 |
. |
匹配任意单个字符 (包括回车符) |
/c..l/ |
匹配字母c,然后两个任意字符,在以l结尾的行 |
* |
重复0个或多个前一个字符 |
/a*cool/ |
匹配0个或多个a之后紧跟着cool的行比如:cool、aaacool |
[] |
匹配指定字符内的任一个字符 |
/^[abc]/ |
匹配以字母a或b或c开头的行 |
[^] |
匹配不再指定字符组内的任一个字符 |
/^[^abc]/ |
匹配不以字母a或b或c开头的行 |
() |
子表达式组合 |
/(cool)+/ |
表示一个或多个cool组合,当有一些字符需要组合时,使用括号括起来 |
| |
或者的意思 |
/(cool)|B/ |
匹配错了或者字母B的行 |
awk默认不支持的元字符,和需要添加参数才能支持的元字符 |
|||
x{m} x{m,} x{m,n} |
x重复m次 x重复至少m次 x重复至少m次,但不超过n次 需要指定参数: --posix或者 --re-interval 没有该参数不能使用这种模式 |
/cool{5}/ |
需要注意一点的是,cool加括号或不加括号的区别,x可以使字符串也可以是一个字符,所以/cool\{5\}/表示匹配coo在加上5个l,及coolllll, /\(cool\)\{2,\}/则表示匹配coolcoolcoolcool等 |
/(cool){2,}/ |
|||
/(cool){5,6}/ |
|||
|
2.2.1、awk正则表达式匹配操作符
awk正则匹配操作符
~:用于对记录或区域的表达式进行匹配
!~:用于表达与~相反的意思
2.2.2、awk正则表达式匹配行
和下面的效果是一样的
说明:
awk只用正则表达式的时候默认匹配整行的即'$0~/^root/'与'/^root/'是一样的
2.3、练习
练习1:显示zhao姓第二次充值金额和姓名
练习2:显示liu的姓氏和ID号
练习3:显示所有以5开头的ID号码的人全名和ID号码
练习4:显示所有以一个s或l开头的名全名
练习5:显示所有ID号码最后以为数字是2或3的人全名
练习6:显示er的充值,每个值以¥开头
练习7:显示所有人全名,以姓名格式无空格
2.4、比较表达式作为模式
awk是一种编程语言,能够进行更为复杂的判断,当条件为真时候,awk就执行相关的action。主要是在针对某一区域做出相关的判断,比如打印成绩在80以上的行,这样就必须对这一区域作比较判断,下表列出了awk可以使用的关系运算符,可以用来比较数字者字符串,还有正则表达式。当正则表达式为真时候,表达式结果为1,否之为0,只有表达式为真,awk才执行相关的action。
运算符 |
含义 |
示例 |
< |
小于 |
x>y |
<= |
小于或等于 |
x<=y |
== |
等于 |
x==y |
!= |
不等于 |
x!-y |
>= |
大于或等于 |
x>=y |
> |
大于 |
x<y |
以上的运算符均是针对数字,下面两个运算符之前已有示例,针对字符串 |
||
~ |
于正则表达式匹配 |
x~/y/ |
!~ |
与正则表达式不匹配 |
x!~y |
例:
2.5、范围模式
pattern1 |
, |
pattern2 |
从哪里来 |
到 |
哪里去 |
条件1 |
, |
条件2 |
范围模式简单理解就是从哪里来,到哪里去。
匹配从条件1开始到条件2介绍的范围
awk的范围模式,与sed类似,但是又有不同,awk不能直接使用行号来作为范围起始地址,因为awk具有内置变量NR来存储记录号,所有需要使用NR=1,NR=5这样来使用。
范围模式处理原则是:先匹配从第一个模式的首次出现到第二个模式的首次出现之间的内容,执行action。然后匹配从第一个模式的下一次出现到第二个模式的下一次出现,直到文本结束。如果匹配到第一个模式而没有匹配到第二个模式,则awk处理从第一个模式开始直到文本结束全部行,如果第一个模式不匹配,就算第一个模式匹配,awk依旧不处理任何行。
2.5.1、BEGIN模块
BEGIN模块在awk读取文件之前就执行,一般用来定义我们的内置变量(预定义变量,eg:FS,RS),可以输出表头(类似excel表格名称)
BEGIN模式,自定义变量,给内容变量赋值等,都是用过,需要注意的是BEGIN模式后面要接跟一夜action操作块,包含在大括号内。awk必须在对输入文件进行任何处理前限制性BEGIN里的动作(action)我们可以不要任何输入文件们就可以对BEGIN模块进行测试,因为awk需要限制性BEGIN模式,才对输入文件做处理。BEGIN模式常常被用来修改ORS,RS,FS,OFS等的值
2.6、取IP地址
也可以写成:
注: 命令行-F本质就是修改的FS变量
2.6.1、第二个作用,在读取文件之前输出写提示性信息,表头
显示文件awkfile.txt的第一列和第三列(前期准备的测试文件 /etc/passwd前10行)并在第一行输出username和UID
2.6.2、第三种用法,使用BEGIN模块的特殊性质进行测试
简单输出内容
运行计算
和变量相关的操作
2.6.3、第四种用法:配合getline读取文件
直接定义,直接使用即可
awk中字母会被认为是变量,如果真的要给一个变量赋值字母(字符串),使用双引号。
说明:
没有文件awk依旧可以处理BEGIN模式下的动作(命令)
2.6.4、END模式
END在awk读取完所有的文件的时候,在执行END模块,一般用来输出一个结果(累加,数组结果),也可以是和BEGIN模块类似的结尾标识信息。
2.6.5、统计/etc/services文件里面的空行数量
第一步:统计空行个数
第二部:输出最后结果
awk编程思想:
1.先处理,最后在END模式输出。
2. {print NR,$0} body模块处理,处理完毕后
3. END{print "end of file"}输出一个结果
awk的调试技巧
让awk显示出每一步的执行结果
一般通过print来配合完成
几种常用的运算表达式
i=i+1 ==>i++
i=i+2 ==> i+=2
i=i+$0 ==> i+=$0
2.7、总结:
1、awk命令核心由模式和动作组成,就是‘找谁{干啥}’
2、模式就是条件,动作就是具体干什么
a、正则表达式:必须掌握正则
b、条件表达式:比大小,比较是否相等
c、范围表达式:从哪里来到哪里
3. 注意BEGIN或END模块只能有一个。BEGIN{}BEGIN{}或END{}END{}都是错误的
4、找谁干啥模块,可以是多个
a、'NR==2{print $1}NR==5{print $0}'
b、awk -F ":" 'NR==1{print NR,$0}NR==2{print NR,$NF}' awkfile.txt
内容为小白学习时的笔记,写出来供大家参考