# awk从放弃到入门（1）：awk基础 （通俗易懂，快进来看）

- 80

- A+

所属分类：Linux基础 常用命令

在本博客中，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对文本的格式化能力你体会到了吗？

我的微信公众号
关注"实用运维笔记"微信公众号，当博客中有新文章时，可第一时间得知哦~
赞 603
赏
分享

- awk
- 常用命令

- 版权声明：本站原创文章，于2017年3月19日20:18:59，由 朱双印 发表，共 3028 字。
- 如需转载，请在文章头部注明出处：awk从放弃到入门（1）：awk基础 （通俗易懂，快进来看） | 朱双印博客

awk从放弃到入门（11）：拾遗之”三元运算”与”打印奇偶行”
awk从放弃到入门（10）：awk内置函数
awk从放弃到入门（9）：awk数组详解
awk从放弃到入门（8）：awk动作总结之二

### 发表评论取消回复

欢迎 pangzi 再次光临！
修改信息

正在提交, 请稍候...
#

昵称*

邮箱*

网址

有回复时邮件通知我

## 目前评论：80 其中：访客 65 博主 15

2. 秦柏 2
   回复 2020年10月12日 下午4:00 沙发

   感谢博主，博主的文章真的是篇篇精华

4. 会发光 0
   回复 2020年9月28日 下午4:46 板凳

   好多图片还是无法正常显示呀，博主能不能搞一下

   - 朱双印 Admin
     回复 2020年9月28日 下午8:08 1层

     @会发光 我这边复现不出问题，这边都是正常显示的，所以没有办法排查原因，之前有朋友说是因为http地址的图片的原因，不知道怎样复现，说是浏览器有https保护，我没有测试出具体问题，那边不能正常显示的都是http地址的图片吗，https地址的图片有没有不能正常显示的

6. 夏日之星 0
   回复 2020年8月10日 上午10:02 地板

   写的太详细了，对于小白来说非常有用！！！

   - 夜不语 1
     回复 2020年9月25日 下午4:51 1层

     @夏日之星 马哥教育了解一下

8. 买了否冷 0
   回复 2020年6月12日 上午9:36 4楼

   善良如你，可否通俗的讲解下sed命令

10. 一根烟的故事 1
    回复 2020年4月28日 下午2:40 5楼

    找到你的博客要从一个友情链接说起 哈哈哈

12. 迷之夏天 3
    回复 2020年4月20日 下午2:48 6楼

    打卡，博主最帅，你的智慧我要收下了～～～

14. 沉默寡言 0
    回复 2020年2月29日 下午9:31 7楼

    真的很棒。拷贝了一些到个人有道笔记仅做自己学习之用。😄虽然加了禁用复制，但我想用到awk命令的人应该都能拷贝出吧。那些复制了可能会说自己写的人的确会很讨厌。还有名称可以用水印的方式加图片中间，不然这样一截取，不截最后一行完全不影响的啊

16. 加特勒 0
    回复 2020年1月2日 下午4:04 8楼

    良心之作，浅显易懂，感谢博主的分享。

18. 不忘初心 0
    回复 2019年10月29日 下午4:53 9楼

    不错不错,学习了.

20. darkidot 2
    回复 2019年10月29日 下午2:44 10楼

    写的很仔细、加油

22. 666 0
    回复 2019年10月23日 上午10:59 11楼

    真的是好教材，对与我们这种小白来说，一字一句扣的清清楚楚的，感谢

24. mightusa 0
    回复 2019年9月16日 下午2:16 12楼

    很棒

26. Franco 1
    回复 2019年8月14日 下午11:49 13楼

    感谢 看了豁然开朗 因为工作原因要处理一些日志文件 以后会多来学习技术 赞赞赞 比那些辣鸡CSDN互相抄的不知道高到哪去了

28. kai 0
    回复 2019年8月3日 下午7:22 14楼

    真棒！真的赞!

30. 迈克尔西门庆 2
    回复 2019年7月25日 下午12:35 15楼

    这系列真是优秀的不像话！！！！真的获益匪浅，忍不住想说脏话，牛逼（破音）！

32. 迈克尔西门庆 2
    回复 2019年7月25日 下午12:32 16楼

    为什么我’print{$i}’ 和 ‘print{$0}’ 的结果是一样的？

34. grandly 0
    回复 2019年7月18日 下午4:43 17楼

    博客写的很好，我不是做运维的，只是刚巧碰到要用awk这个命令，相比网上那些，你写的确实比网上那些讲的简单明白多了，已关注博客，会经常来看。
    然后说一下有一点很不爽的是，你的博客页面禁用文本选择复制功能，右键也不能点，我想复制一下命令都不行。
    想来你应该是防止别人转载你的原创内容的，但你这样也就能防一下那些不懂技术的小白，稍微懂点的分分钟给你copy过去。
    这么做得不偿失，还让认真看你问的读者体验非常不好。
    认真看了一下你的网站，真的有学到不少linux知识，感谢无私分享。

    - 朱双印 Admin
      回复 2019年7月19日 上午10:02 1层

      @grandly 友链已加，加油，共勉～

    - 朱双印 Admin
      回复 2019年7月19日 上午10:09 1层

      @grandly 嗯嗯，不过不是每个人都是这样想的，你可能没有见过那些拷贝了你的文章还恶意留言，或者攻击你网站的人，不过谢谢你的捧场，我不能做到每个人都满意，我只能尽量做好的情况下，不让自己感觉憋屈，哈哈，谢谢捧场了，加油，共勉～

36. 萌新 1
    回复 2019年6月11日 下午1:01 18楼

    感谢博主，加油。

38. YFourGold 0
    回复 2019年5月5日 下午2:47 19楼

    知识点全面，支持，作为一名运维人员，对于我来说很多都是新知识，已收藏，学习。

40. 小小白 1
    回复 2019年3月19日 下午8:09 20楼

    是师出马哥吗？感觉风格有点像。厉害了

42. 帅汪 1
    回复 2019年1月23日 上午10:22 21楼

    请问这个网站也是自己做的吗？

44. 帅汪 1
    回复 2019年1月23日 上午10:21 22楼

    厉害 解释的非常清楚 容易理解

46. hybcloud 0
    回复 2018年12月22日 上午10:33 23楼

    真的很棒，感谢！

48. keneyh 0
    回复 2018年12月17日 上午10:17 24楼

    写的真的好，通俗易懂。看起来也不枯燥。谢谢作者！

50. qcheen 0
    回复 2018年11月20日 上午10:35 25楼

    博主的文章写得都很容易懂，是个认真写技术文章的人，果断收藏！

52. 单位的风 1
    回复 2018年11月14日 下午2:56 26楼

    突发奇感
    若果这样写：awk ‘END{print $1,$2} {print “aa”,”bb”}’ test
    结果如下：
    aa bb
    aa bb
    8ua 456

54. 单位的风 1
    回复 2018年11月14日 下午2:40 27楼

    正要学习awk，讲的很好。

56. 花影依旧摇曳 0
    回复 2018年11月13日 下午10:34 28楼

    受益匪浅，非常感谢

58. 西门大官人 2
    回复 2018年9月29日 下午3:17 29楼

    请问双印是BIGEN“老师”吗？ 这授课水平直追“叫兽”了、

60. 粽子 0
    回复 2018年9月5日 下午5:59 30楼

    正好要用到awk！必须给博主一个赞呀！

62. 小小 1
    回复 2018年9月3日 下午8:26 31楼

    通俗易懂

64. 小小 1
    回复 2018年9月3日 下午8:25 32楼

    通俗易懂，笔者可以当讲师了

66. 落单的小野鸭 1
    回复 2018年8月23日 上午10:04 33楼

    第一次看技术文章看的热血沸腾，真正明白了什么叫浅显易懂，发自内心的感谢博主，找对文章有时候比自己努力更重要，希望可以看到博主出书。加油

68. xx 0
    回复 2018年8月13日 下午5:07 34楼

    写的很好
    赞一个

70. lqy007700 0
    回复 2018年7月31日 下午1:59 35楼

    写的很详细，正在学习

72. 求知的菜鸟 1
    回复 2018年7月20日 下午2:11 36楼

    博主这种人值得去尊敬，非常感谢博主所做的一切，加油。

74. 蜗牛 0
    回复 2018年7月9日 下午7:30 37楼

    博主文章写的非常好，持续关注，希望可以转载，好东西忍不住分享。

76. 宇宙尽头 2
    回复 2018年6月13日 下午8:33 38楼

    Linux的知识很杂，博主可以把这些知识系统的总结下来，真的对学习和积累帮助很大。谢谢

78. king 1
    回复 2018年6月8日 下午4:30 39楼

    博主 为何这么优秀 大声告诉我

80. wangruirui 0
    回复 2018年4月12日 下午3:19 40楼

    厉害了 学习了

82. 小柯 1
    回复 2018年4月8日 上午10:51 41楼

    太牛批了，犹如发现了新大陆。加油哟

84. 大师兄啊 0
    回复 2018年3月29日 下午4:53 42楼

    怎么说了，看了这么多技术博客，很多博客文章基本都是转载的，很多时候连原文的内容正确性也不深究，往往很多错误，而且又晦涩难懂。这个博客是我见过最能把复杂的东西说清楚的一个，可以看得出博主真的很认真的在维护这个博客。赞一个。

86. 天蓝蓝 1
    回复 2018年3月9日 上午10:54 43楼

    厉害了

88. ss 0
    回复 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

90. YY 0
    回复 2018年1月22日 下午5:13 45楼

    写的真心不错， 我这种自以为会完全看不懂的人都觉得有兴趣了， 点赞点赞

92. suzhi82 1
    回复 2017年11月29日 下午4:48 46楼

    感谢朱兄的系列文章，让我对awk 和iptables 有了进一步的认识。希望后面能出个关于sed 的系列，这样grep、awk、sed 三杰就齐了。

94. suzhi82 1
    回复 2017年11月5日 下午12:34 47楼

    请问朱兄有否打算出一个详解sed 的系列？

    - 朱双印 Admin
      回复 2017年11月5日 下午1:39 1层

      @suzhi82 其实我的计划是把之前所有的笔记都重写一遍，但是现在真的应付不过来，工作太忙加班，如果写一篇高质量的文章，需要很多时间，所以只能抽时间吧，计划赶不上变化，有空就会写，到时候会在微信上通知大家，谢谢捧场了~

      - 艾窝窝 0
        回复 2018年7月4日 下午8:56 2层

        @朱双印 想加你微信，跟进博客

96. jyz 0
    回复 2017年10月18日 下午5:49 48楼

    完全新手，用xshell编程，想问一下为什么输入cat test
    显示 cat: test: No such file or directory

98. 杜嘉嘉 2
    回复 2017年9月25日 上午10:33 49楼

    昨天看您的iptables 文章，看到2点多，受益匪浅，非常感谢您提供的帮助，希望您能继续写好文~

    - 朱双印 Admin
      回复 2017年9月25日 下午6:55 1层

      @杜嘉嘉 感谢客官肯定，有你的支持我会继续写博客给大家的，只是最近特别忙，所以暂停了，谢谢捧场~~

100. 紫色之心 0
     回复 2017年9月19日 下午2:30 50楼

     不错哦

     - 朱双印 Admin
       回复 2017年9月20日 上午8:30 1层

       @紫色之心 客官捧场~感谢~~

102. Pandas 0
     回复 2017年9月13日 下午9:07 51楼

     写的很好，受教了 谢谢

     - 朱双印 Admin
       回复 2017年9月14日 上午9:06 1层

       @Pandas 感谢客官肯定~~

104. 易知难 4
     回复 2017年7月28日 下午1:36 52楼

     记笔记：
     1.BEGIN：在处理文本之前执行比如初始化代码
     2. END： 处理文本之后执行，比如用于执行最终计算或打印应该出现在输出流结尾的摘要信息
     3.$0等内置变量不能在外侧加双引号，如果加了会被当作字符处理

     - 朱双印 Admin
       回复 2017年7月28日 下午11:38 1层

       @易知难 不止内置变量，自定义变量也是一样的，
       很好，能有自己的思考~~加油，坚持住~~~

106. 易知难 4
     回复 2017年7月28日 下午1:27 53楼

     博主写的很好，以后常来逛！比直接看文档好多了

108. caosen 0
     回复 2017年7月5日 下午11:31 54楼

     你好，请问 ‘BEGIN {print $3}打印出是空白的 说明BEGIN不可以这么用吗？

     - 朱双印 Admin
       回复 2017年7月6日 上午8:51 1层

       @caosen BEGIN模式中，还没有开始处理文本中的行，BEGIN模式中的动作，会在开始处理文本行之前执行

110. hesheng 2
     回复 2017年6月27日 上午10:13 55楼

     天天来看

     - 朱双印 Admin
       回复 2017年6月27日 上午10:40 1层

       @hesheng 666 , 我莫名的喜欢这四个字
       感谢捧场呦~~~

112. echo 6
     回复 2017年6月13日 下午10:37 56楼

     哇 对于我来是全新新新的知识 好像很刺激的样子 哈哈

     - 朱双印 Admin
       回复 2017年6月13日 下午10:46 1层

       @echo 兄弟，我发现你的评论级别目前是最高的 ，看着很刺激的样子 ，哈哈，加油，兄弟~~

       - echo 6
         回复 2017年6月17日 下午9:07 2层

         @朱双印 有几天没来，今天继续上次没看完的 哈哈

         - 朱双印 Admin
           回复 2017年6月17日 下午9:35 3层

           @echo 有毅力~加油~~！

114. GMFTBY 1
     回复 2017年5月19日 下午11:02 57楼

     孜孜不倦，感谢感谢，学习了

116. whoami 0
     回复 2017年5月4日 上午9:51 58楼

     写的不错 为什么不能复制呢

118. just_wkj 1
     回复 2017年4月18日 下午12:36 59楼

     讲的很好.学习了

     - 朱双印 Admin
       回复 2017年4月18日 下午1:41 1层

       @just_wkj 谢谢夸奖，能对你有所帮助才是最好的。

120. 不会游泳的脚鸟 0
     回复 2017年4月17日 下午2:15 60楼

     从放弃到入门，这个名字起的，就服你～～

     - 朱双印 Admin
       回复 2017年4月17日 下午3:29 1层

       @不会游泳的脚鸟 这位客官你懂我~~~

122. firegod 0
     回复 2017年3月28日 下午11:33 61楼

     你好，你这个blog 是用 wp 创建的吗？还是自己写的啊

     - 朱双印 Admin
       回复 2017年3月28日 下午11:54 1层

       @firegod 是用wp创建的

     - Quincy.Coder 1
       回复 2018年8月16日 上午8:44 1层

       @firegod 酷炫的博客，我也想创建这么个博客，好羡慕~

- 文章目录

×
×
拖拽到此处
图片将完成下载