- A+
在本博客中,AWK是一个系列文章,本人会尽量以通俗易懂的方式递进的总结awk命令的相关知识点。
awk系列博文直达链接:AWK命令总结之从放弃到入门
我们先来用专业的术语描述一下awk是什么,如果你看不懂,没关系,我们会再用"大白话"解释一遍。
awk是一个报告生成器,它拥有强大的文本格式化的能力,这就是专业的说法。
你可能不理解所谓的报告生成器中的"报告"是什么,你可以把"报告"理解为"报表"或者"表格",也就是说,我们可以利用awk命令,将一些文本整理成我们想要的样子,比如把一些文本整理成"表"的样子,然后再展示出来,刚才概念中提到的"文本格式化的能力",也就是这个意思,其实这样说可能还是不太容易理解,不用着急,当你看到后面的"示例"时,自然会明白awk所擅长的"文本格式化"能力是什么。
awk是由Alfred Aho 、Peter Weinberger 和 Brian Kernighan这三个人创造的,awk由这个三个人的姓氏的首个字母组成。
awk早期是在unix上实现的,所以,我们现在在linux的所使用的awk其实是gawk,也就是GNU awk,简称为gawk,awk还有一个版本,New awk,简称为nawk,但是linux中最常用的还是gawk。
awk其实是一门编程语言,它支持条件判断、数组、循环等功能。所以,我们也可以把awk理解成一个脚本语言解释器。
grep 、sed、awk被称为linux中的"三剑客"。
我们总结一下这三个"剑客"的特长。
grep 更适合单纯的查找或匹配文本
sed 更适合编辑匹配到的文本
awk 更适合格式化文本,对文本进行较复杂格式处理
此处,我们只总结 awk
awk基础
awk基本语法如下,看不懂没关系,我们会慢慢举例。
awk [options] 'program' file1 , file2 , ```
对于上述语法中的program来说,又可以细分成pattern和action,也就是说,awk的基本语法如下
awk [options] 'Pattern{Action}' file
从字面上理解 ,action指的就是动作,awk擅长文本格式化,并且将格式化以后的文本输出,所以awk最常用的动作就是print和printf,因为awk要把格式化完成后的文本输出啊,所以,这两个动作最常用。
我们先从最简单用法开始了解awk,我们先不使用[options] ,也不指定pattern,直接使用最简单的action,从而开始认识awk,示例如下
上图中,我们只是使用awk执行了一个打印的动作,将testd文件中的内容打印了出来。
好了,现在,我们来操作一下另一个类似的场景。
上图中的示例没有使用到options和pattern,上图中的awk '{print $5}',表示输出df的信息的第5列,$5表示将当前行按照分隔符分割后的第5列,不指定分隔符时,默认使用空格作为分隔符,细心的你一定发现了,上述信息用的空格不止有一个,而是有连续多个空格,awk自动将连续的空格理解为一个分割符了,是不是比cut命令要简单很多,这样比较简单的例子,有利于我们开始了解awk。
awk是逐行处理的,逐行处理的意思就是说,当awk处理一个文本时,会一行一行进行处理,处理完当前行,再处理下一行,awk默认以"换行符"为标记,识别每一行,也就是说,awk跟我们人类一样,每次遇到"回车换行",就认为是当前行的结束,新的一行的开始,awk会按照用户指定的分割符去分割当前行,如果没有指定分割符,默认使用空格作为分隔符。
$0 表示显示整行 ,$NF表示当前行分割后的最后一列($0和$NF均为内置变量)
注意,$NF 和 NF 要表达的意思是不一样的,对于awk来说,$NF表示最后一个字段,NF表示当前行被分隔符切开以后,一共有几个字段。
也就是说,假如一行文本被空格分成了7段,那么NF的值就是7,$NF的值就是$7, 而$7表示当前行的第7个字段,也就是最后一列,那么每行的倒数第二列可以写为$(NF-1)。
我们也可以一次输出多列,使用逗号隔开要输出的多个列,如下,一次性输出第一列和第二列
同理,也可以一次性输出多个指定的列,如下图
我们发现,第一行并没有第5列,所以并没有输出任何文本,而第二行有第五列,所以输出了。
除了输出文本中的列,我们还能够添加自己的字段,将自己的字段与文件中的列结合起来,如下做法,都是可以的。
从上述实验中可以看出,awk可以灵活的将我们指定的字符与每一列进行拼接,或者把指定的字符当做一个新列插入到原来的列中,也就是awk格式化文本能力的体现。
但是要注意,$1这种内置变量的外侧不能加入双引号,否则$1会被当做文本输出,示例如下
我们也可以输出整行,比如,如下两种写法都表示输出整行。
我们说过,awk的语法如下
awk [options] 'Pattern{Action}' file
而且我们说过awk是逐行处理的, 刚才已经说过了最常用的Action:print
现在,我们来认识下一Pattern,也就是我们所说的模式
不过,我们准备先把awk中最特殊的模式展示给大家,以后再介绍普通的模式,因为普通模式需要的篇幅比较长,所以我们先来总结特殊模式。
AWK 包含两种特殊的模式:BEGIN 和 END。
BEGIN 模式指定了处理文本之前需要执行的操作:
END 模式指定了处理完所有行之后所需要执行的操作:
什么意思呢?光说不练不容易理解,我们来看一些小例子,先从BEGIN模式开始,示例如下
上述写法表示,在开始处理test文件中的文本之前,先执行打印动作,输出的内容为"aaa","bbb".
也就是说,上述示例中,虽然指定了test文件作为输入源,但是在开始处理test文本之前,需要先执行BEGIN模式指定的"打印"操作
既然还没有开始逐行处理test文件中的文本,那么是不是根本就不需要指定test文件呢,我们来试试。
经过实验发现,还真是,我们并没有给定任何输入来源,awk就直接输出信息了,因为,BEGIN模式表示,在处理指定的文本之前,需要先执行BEGIN模式中指定的动作,而上述示例没有给定任何输入源,但是awk还是会先执行BEGIN模式指定的"打印"动作,打印完成后,发现并没有文本可以处理,于是就只完成了"打印 aaa bbb"的操作。
这个时候,如果我们想要awk先执行BEGIN模式指定的动作,再根据执我们自定义的动作去操作文本,该怎么办呢?示例如下
上图中,蓝色标注的部分表示BEGIN模式指定的动作,这部分动作需要在处理指定的文本之前执行,所以,上图中先打印出了"aaa bbb",当BEGIN模式对应的动作完成后,在使用后面的动作处理对应的文本,即打印test文件中的第一列与第二列,这样解释应该比较清楚了吧。
看完上述示例,似乎更加容易理解BEGIN模式是什么意思了,BEGIN模式的作用就是,在开始逐行处理文本之前,先执行BEGIN模式所指定的动作。以此类推,END模式的作用就一目了然了,举例如下。
聪明如你一定明白了,END模式就是在处理完所有的指定的文本之后,需要指定的动作。
那么,我们可以结合BEGIN模式和END模式一起使用。示例如下
上述示例中返回的结果有没有很像一张"报表",有"表头" 、"表内容"、 "表尾",awk对文本的格式化能力你体会到了吗?
_files/2017-04-27-1720365637.png)
2020年10月12日 下午4:00 沙发
感谢博主,博主的文章真的是篇篇精华
2020年9月28日 下午4:46 板凳
好多图片还是无法正常显示呀,博主能不能搞一下
_files/icon_evil.gif)
2020年9月28日 下午8:08 1层
@会发光 我这边复现不出问题,这边都是正常显示的,所以没有办法排查原因,之前有朋友说是因为http地址的图片的原因,不知道怎样复现,说是浏览器有https保护,我没有测试出具体问题,那边不能正常显示的都是http地址的图片吗,https地址的图片有没有不能正常显示的
2020年8月10日 上午10:02 地板
写的太详细了,对于小白来说非常有用!!!
2020年9月25日 下午4:51 1层
@夏日之星 马哥教育了解一下
2020年6月12日 上午9:36 4楼
善良如你,可否通俗的讲解下sed命令
2020年4月28日 下午2:40 5楼
找到你的博客要从一个友情链接说起 哈哈哈
2020年4月20日 下午2:48 6楼
打卡,博主最帅,你的智慧我要收下了~~~
2020年2月29日 下午9:31 7楼
真的很棒。拷贝了一些到个人有道笔记仅做自己学习之用。😄虽然加了禁用复制,但我想用到awk命令的人应该都能拷贝出吧。那些复制了可能会说自己写的人的确会很讨厌。还有名称可以用水印的方式加图片中间,不然这样一截取,不截最后一行完全不影响的啊
2020年1月2日 下午4:04 8楼
良心之作,浅显易懂,感谢博主的分享。
2019年10月29日 下午4:53 9楼
不错不错,学习了.
2019年10月29日 下午2:44 10楼
写的很仔细、加油
2019年10月23日 上午10:59 11楼
真的是好教材,对与我们这种小白来说,一字一句扣的清清楚楚的,感谢
2019年9月16日 下午2:16 12楼
很棒
2019年8月14日 下午11:49 13楼
感谢 看了豁然开朗 因为工作原因要处理一些日志文件 以后会多来学习技术 赞赞赞 比那些辣鸡CSDN互相抄的不知道高到哪去了
2019年8月3日 下午7:22 14楼
真棒!真的赞!
2019年7月25日 下午12:35 15楼
这系列真是优秀的不像话!!!!真的获益匪浅,忍不住想说脏话,牛逼(破音)!
2019年7月25日 下午12:32 16楼
为什么我’print{$i}’ 和 ‘print{$0}’ 的结果是一样的?
2019年7月18日 下午4:43 17楼
博客写的很好,我不是做运维的,只是刚巧碰到要用awk这个命令,相比网上那些,你写的确实比网上那些讲的简单明白多了,已关注博客,会经常来看。
然后说一下有一点很不爽的是,你的博客页面禁用文本选择复制功能,右键也不能点,我想复制一下命令都不行。
想来你应该是防止别人转载你的原创内容的,但你这样也就能防一下那些不懂技术的小白,稍微懂点的分分钟给你copy过去。
这么做得不偿失,还让认真看你问的读者体验非常不好。
认真看了一下你的网站,真的有学到不少linux知识,感谢无私分享。
2019年7月19日 上午10:02 1层
@grandly 友链已加,加油,共勉~
2019年7月19日 上午10:09 1层
@grandly 嗯嗯,不过不是每个人都是这样想的,你可能没有见过那些拷贝了你的文章还恶意留言,或者攻击你网站的人,不过谢谢你的捧场,我不能做到每个人都满意,我只能尽量做好的情况下,不让自己感觉憋屈,哈哈,谢谢捧场了,加油,共勉~
2019年6月11日 下午1:01 18楼
感谢博主,加油。
2019年5月5日 下午2:47 19楼
知识点全面,支持,作为一名运维人员,对于我来说很多都是新知识,已收藏,学习。
2019年3月19日 下午8:09 20楼
是师出马哥吗?感觉风格有点像。厉害了
2019年1月23日 上午10:22 21楼
请问这个网站也是自己做的吗?
2019年1月23日 上午10:21 22楼
厉害 解释的非常清楚 容易理解
2018年12月22日 上午10:33 23楼
真的很棒,感谢!
2018年12月17日 上午10:17 24楼
写的真的好,通俗易懂。看起来也不枯燥。谢谢作者!
2018年11月20日 上午10:35 25楼
博主的文章写得都很容易懂,是个认真写技术文章的人,果断收藏!
2018年11月14日 下午2:56 26楼
突发奇感
若果这样写:awk ‘END{print $1,$2} {print “aa”,”bb”}’ test
结果如下:
aa bb
aa bb
8ua 456
2018年11月14日 下午2:40 27楼
正要学习awk,讲的很好。
2018年11月13日 下午10:34 28楼
受益匪浅,非常感谢
2018年9月29日 下午3:17 29楼
请问双印是BIGEN“老师”吗? 这授课水平直追“叫兽”了、
2018年9月5日 下午5:59 30楼
正好要用到awk!必须给博主一个赞呀!
2018年9月3日 下午8:26 31楼
通俗易懂
2018年9月3日 下午8:25 32楼
通俗易懂,笔者可以当讲师了
2018年8月23日 上午10:04 33楼
第一次看技术文章看的热血沸腾,真正明白了什么叫浅显易懂,发自内心的感谢博主,找对文章有时候比自己努力更重要,希望可以看到博主出书。加油
2018年8月13日 下午5:07 34楼
写的很好
赞一个
2018年7月31日 下午1:59 35楼
写的很详细,正在学习
2018年7月20日 下午2:11 36楼
博主这种人值得去尊敬,非常感谢博主所做的一切,加油。
2018年7月9日 下午7:30 37楼
博主文章写的非常好,持续关注,希望可以转载,好东西忍不住分享。
2018年6月13日 下午8:33 38楼
Linux的知识很杂,博主可以把这些知识系统的总结下来,真的对学习和积累帮助很大。谢谢
2018年6月8日 下午4:30 39楼
博主 为何这么优秀 大声告诉我
2018年4月12日 下午3:19 40楼
厉害了 学习了
2018年4月8日 上午10:51 41楼
太牛批了,犹如发现了新大陆。加油哟
2018年3月29日 下午4:53 42楼
怎么说了,看了这么多技术博客,很多博客文章基本都是转载的,很多时候连原文的内容正确性也不深究,往往很多错误,而且又晦涩难懂。这个博客是我见过最能把复杂的东西说清楚的一个,可以看得出博主真的很认真的在维护这个博客。赞一个。
2018年3月9日 上午10:54 43楼
厉害了
2018年1月23日 下午8:58 44楼
讲的很好!博客也好!awk还有更深入的用法,希望朱大神可以再补充一些,曾经解决下面的问题费了我好大劲才研究好,你参考一下:
echo $a | awk -F ‘,’ -v time=$time -v lack=$lack ‘{OFS=”,”} { if ($7==””&&time!=””) {$7=time;$6=lack} {print $0}}’ >> ./merge.csv
2018年1月22日 下午5:13 45楼
写的真心不错, 我这种自以为会完全看不懂的人都觉得有兴趣了, 点赞点赞
2017年11月29日 下午4:48 46楼
感谢朱兄的系列文章,让我对awk 和iptables 有了进一步的认识。希望后面能出个关于sed 的系列,这样grep、awk、sed 三杰就齐了。_files/icon_mrgreen.gif)
2017年11月5日 下午12:34 47楼
请问朱兄有否打算出一个详解sed 的系列?
2017年11月5日 下午1:39 1层
@suzhi82 其实我的计划是把之前所有的笔记都重写一遍,但是现在真的应付不过来,工作太忙加班,如果写一篇高质量的文章,需要很多时间,所以只能抽时间吧,计划赶不上变化,有空就会写,到时候会在微信上通知大家,谢谢捧场了~
2018年7月4日 下午8:56 2层
@朱双印 想加你微信,跟进博客
2017年10月18日 下午5:49 48楼
完全新手,用xshell编程,想问一下为什么输入cat test
显示 cat: test: No such file or directory
2017年9月25日 上午10:33 49楼
昨天看您的iptables 文章,看到2点多,受益匪浅,非常感谢您提供的帮助,希望您能继续写好文~
2017年9月25日 下午6:55 1层
@杜嘉嘉 感谢客官肯定,有你的支持我会继续写博客给大家的,只是最近特别忙,所以暂停了,谢谢捧场~~
2017年9月19日 下午2:30 50楼
不错哦
2017年9月20日 上午8:30 1层
@紫色之心 客官捧场~感谢~~
2017年9月13日 下午9:07 51楼
写的很好,受教了 谢谢
2017年9月14日 上午9:06 1层
@Pandas 感谢客官肯定~~
2017年7月28日 下午1:36 52楼
记笔记:
1.BEGIN:在处理文本之前执行比如初始化代码
2. END: 处理文本之后执行,比如用于执行最终计算或打印应该出现在输出流结尾的摘要信息
3.$0等内置变量不能在外侧加双引号,如果加了会被当作字符处理
2017年7月28日 下午11:38 1层
@易知难 不止内置变量,自定义变量也是一样的,
很好,能有自己的思考~~加油,坚持住~~~
2017年7月28日 下午1:27 53楼
博主写的很好,以后常来逛!比直接看文档好多了_files/icon_mrgreen.gif)
2017年7月5日 下午11:31 54楼
你好,请问 ‘BEGIN {print $3}打印出是空白的 说明BEGIN不可以这么用吗?
2017年7月6日 上午8:51 1层
@caosen BEGIN模式中,还没有开始处理文本中的行,BEGIN模式中的动作,会在开始处理文本行之前执行
2017年6月27日 上午10:13 55楼
天天来看
2017年6月27日 上午10:40 1层
@hesheng 666 , 我莫名的喜欢这四个字_files/icon_mrgreen.gif)
感谢捧场呦~~~
2017年6月13日 下午10:37 56楼
哇 对于我来是全新新新的知识 好像很刺激的样子 哈哈
2017年6月13日 下午10:46 1层
@echo 兄弟,我发现你的评论级别目前是最高的
,看着很刺激的样子
,哈哈,加油,兄弟~~
2017年6月17日 下午9:07 2层
@朱双印 有几天没来,今天继续上次没看完的 哈哈
2017年6月17日 下午9:35 3层
@echo 有毅力~加油~~!
2017年5月19日 下午11:02 57楼
孜孜不倦,感谢感谢,学习了
2017年5月4日 上午9:51 58楼
写的不错 为什么不能复制呢
2017年4月18日 下午12:36 59楼
讲的很好.学习了
2017年4月18日 下午1:41 1层
@just_wkj 谢谢夸奖,能对你有所帮助才是最好的。
2017年4月17日 下午2:15 60楼
从放弃到入门,这个名字起的,就服你~~
2017年4月17日 下午3:29 1层
@不会游泳的脚鸟 这位客官你懂我~~~
2017年3月28日 下午11:33 61楼
你好,你这个blog 是用 wp 创建的吗?还是自己写的啊
2017年3月28日 下午11:54 1层
@firegod 是用wp创建的
2018年8月16日 上午8:44 1层
@firegod 酷炫的博客,我也想创建这么个博客,好羡慕~