前面也提到了 awk 和 sed 一样是流式编辑器,它也是针对文档中的行来操作的,一行一行的去执行。awk 比 sed 更加强大,它能做到 sed 能做到的,同样也能做到 sed 不能做到的。awk 工具其实是很复杂的,有专门的书籍来介绍它的应用,不过我认为学那么复杂没有必要,只要能处理日常管理工作中的问题即可。

正则介绍 awk_第1张图片

同样的,做一下准备工作,见下图,
正则介绍 awk_第2张图片
先操作 awk 最简单的功能,指定分隔符 -F ,来查看一下文件 test.txt 的内容,见下图,
正则介绍 awk_第3张图片
接着指定分隔符为“:”,输出第一列,见下图,
正则介绍 awk_第4张图片
上图的操作命令,也不会更改文件的内容,跟 sed 一样。既然可以输出第一列,也可以输出指定的列或是全部输出,输出第三列,见下图,
正则介绍 awk_第5张图片
输出全部的列,用 $0 表示,见下图,
正则介绍 awk_第6张图片
全部输出还有一个简单的命令,不用指定分隔符,不用 -F,见下图,
正则介绍 awk_第7张图片

来试着操作一下,不指定分隔符的情况,先创建一个测试的文件 1.txt ,输入 vim 1.txt ,回车,见下图,
正则介绍 awk_第8张图片
输入上图内容,保存后退出。接着往下操作,
正则介绍 awk_第9张图片
以上说明 awk 忽略 -F 的选项,也就是没有指定默认的分隔符,默认会以空格或是空白字符为分隔符去打印。想要多打印几列,就可以用“,”来显示。
正则介绍 awk_第10张图片
上图中的分隔符,除了空格,也可以使用 # ,要用双引号引起来 "#",见下图,
正则介绍 awk_第11张图片
假如需要分的段比较多的话,用以上操作就会非常麻烦,实际上还有一种方法,等会会说。
接着来说一下 awk 的匹配功能,见下图,
正则介绍 awk_第12张图片
上图第二个命令就是 awk 和 sed 、grep 不同的地方,可以分列匹配查找。awk 同样也支持正则表达式,见下图,
正则介绍 awk_第13张图片
上图命令使用了正则表达式 + 。awk 这边比 grep 和 sed 强大的地方是,使用到正则表达式的时候都不用加选项或是脱义字符。,可以直接写出命令并执行。
awk 也支持同时使用多个表达式,见下图,
正则介绍 awk_第14张图片
上图中,包含 root 和 user 的结果,并没有全部显示出 root 或 user,可以使用命令 grep -E 命令来验证结果。awk 命令也可以用上图 grep -E 的命令形式,结果是一样的,见下图,
正则介绍 awk_第15张图片
接着来看一下数学公式计算的用法,见下图,
正则介绍 awk_第16张图片
上图命令一定要写两个等号 == ,才能表示等于。写一个等号 = 的话就相当于赋值了。{ } 花括号的内容不写的话,默认是全部输出。也可以使用 >= 大于等于号,验证结果之后也是没错的。如果在数值上面用“”双引号引起来的话,是什么结果呢?见下图,
正则介绍 awk_第17张图片
上图的命令,在数值上加了 " " 双引号,相当于 sort 命令不加 -n ,就是以 ASCII 码的排序方式来计算的,命令就会认为双引号里面的内容是字符串而不是数字。所以,命令里面的数字要用来计算的话,就不能加双引号。
还有不等于号,用 != 表示,见下图,
正则介绍 awk_第18张图片
上图命令中 /sbin/nologin 表示的是字符串,所以要用双引号。结果可以看到,显示出来的行里面,最后一段都没有 /sbin/nologin 。其中 != 这边没有使用空格,要注意。

除了上面使用数字进行比较之外,还可以列与列之间进行比较,见下图,
正则介绍 awk_第19张图片
还可以两个条件在一起使用,见下图,
正则介绍 awk
&& 表示并且的意思,注意上面数字使用的是双引号 “”,所以结果出现了 59 。
除了并且之外,还有或者,见下图,
正则介绍 awk_第20张图片
|| 表示或者,两个条件满足其中一个就可以。接着往下操作,
正则介绍 awk_第21张图片
~ 表示匹配包含。
OFS 内置变量,用来表示输出的分隔符,具体用法见下图,
正则介绍 awk_第22张图片
OFS 需要用 { } 花括号括起来,并且用在单引号 ' ' 命令的最前面,接着才是条件和 print 语句。 不写中间的条件的话,就是全部,见下图,
正则介绍 awk_第23张图片
条件里面还可以写入逻辑语句,见下图,
正则介绍 awk_第24张图片
定义输出的分隔符和输出的内容中间,就是条件,中间的条件和后面的 print 可以一起写,用花括号 { } 整个括起来。表示 if $3>1000 ,就输出 1、3、7 列。下面这条命令的写法,就是省略掉了 if ,if 去掉可以去掉很多符号。但是加上 if 之后,比较好理解。
下面再介绍两个内置的变量,除了OFS,还有 NR 和 NF 。NR 表示行,NF 表示列。接着举例子,见下图,
正则介绍 awk_第25张图片
结果显示出来,相当于 grep -n 的作用,显示行号。NF 就是显示列号,见下图,
正则介绍 awk_第26张图片
结果全部是 7 列。
现在不妨改一下文件 test.txt 的内容,输入 vi test.txt ,回车,见下图,
正则介绍 awk_第27张图片
将第一行的内容,删除一列,保存后退出,接着往下操作,
正则介绍 awk_第28张图片
可以看到第一行的列数变为 6 了。
NR 和 NF 还可以作为判断的条件, 具体用法见下图,
正则介绍 awk_第29张图片
上图第一条命令显示的结果是前十行。第二条命令显示还可以两个条件一起用。
接着看下面这个例子,:冒号需要用双引号 ""引起来,
正则介绍 awk_第30张图片
因为 NR 一共只有 7 列,所有结果显示的行,就前面7行有前半部分,
正则介绍 awk_第31张图片
对于上图命令的理解,用这么一段话解释:
awk 是按行处理文件的,每一行都有awk内置变量:NF,NR
NF:是按给定的分隔符,分出来总的段数, 所有$NF,指最后一段。
NR:是当前行的行号。$NR,表示 第N行的第N段。
老师的示例中,每行有7段,所以,前面7行,第一列,分别显示当前行的段。如第一行显示第一段,第二行显示 第二段,第三行显示 第三段。。。。

以上说明,加上$和不加$,是不一样的。
接着来看一个和 == 两个等号相对应的功能,见下图,
正则介绍 awk_第32张图片
可以看到,第一条命令的 = 等号就是赋值,前三行的第一列都变成 root 了。第二条命令的 == 两个等号才是等于的意思。第一条命令的结果没有分隔符,可以输入变量 OFS 来定义分隔符,见第三条命令。
接着再往下操作,见下图,
正则介绍 awk
这边的 tot 是求和的意思, tot=tot+$3 意思是,新的tot的值,为旧的tot的值和$3的值的和。这个 tot 的值之前并不存在,所以默认是 0 ,从 0 开始求和,每一行的第3列相加。相加完成之后,就输出 tot 的值。
这里的END要注意一下,表示所有的行都已经执行,这是awk特有的语法。其实awk连同sed都可以写成一个脚本文件,而且有他们特有的语法,在awk中使用 if 判断、for 循环都是可以的,只是日常管理工作中没有必要使用那么复杂的语句而已。

总结:
-F 指定分隔符
$0 全部输出
两个等号 == ,才能表示等于
数值上加了 " " 双引号,输出结果就是以 ASCII 码的排序方式来计算
!= 表示不等于
&& 表示并且
|| 表示或者
OFS 内置变量,用来表示输出的分隔符
内置变量 NR 表示行,NF 表示列