Linux系统shell程序设计(二)-awk命令详解(理论+实战)

一、awk概述

AWK是一种解释执行的编程语言,它支持条件判断、循环控制等。被设计用来专门处理文本数据。AWK的名称是由它们的设计者的姓氏的首个字母组成的 --- Afred Aho, Peter Weinberger与Brain Kernighan。

由GNU/Linux发布的AWK版本通常被称为GNU AWK,由自由软件基金(Free Software Foundation, FSF)负责开发维护的。目前总共有如下几种不同的AWK版本:

  • AWK --- 这个版本是AWK最原始的版本,它由AT&T实验室开发。
  • NAWK --- New AWK是AWK的改进增强版本。
  • GAWK --- 即GNU AWK,所有的GNU/Linux发行版都包括GAWK,且GAWK完全兼容AWK与NAWK。Linux中最常用的还是GAWK。
     

1.1 AWK的典型应用场景


其实AWK可以做非常多的工作。下面只是其中的一小部分:

  • 文本处理
  • 生成格式化的文本报告
  • 进行算术运算
  • 字符串操作等。

既然AWK也可以做文本处理,它和之前我们学习的grep、sed有啥区别呢?其实grep、sed、awk被称为Linux中的“三剑客”。让我们来看一下这“三剑客”的特长:

grep

更适合单纯的查找或匹配文本。

sed

更适合编辑匹配到的文本。

awk

更适合格式化文本,对文本进行较复杂格式处理。

二、awk工作流程

  • 接下来我们一起学习一下AWK是如何工作的。要想成为AWK专家,你必须的了解其内部工作的原理。
  • AWK执行的流程非常简单:读(Read)、执行(Execute)与重复(Repeat)。下面的流程图描述出了AWK的工作流程:
     
  • 读(Read)

AWK从输入流(文件、管道或标准输入)中读取一行,然后将其存入内存中。

  • 执行(Execute)

对于每一行的输入,所有的AWK命令按顺序执行。

  • 重复(Repeat)

一直重复上述两个过程,直到文件结束。

从上图我们已经了解了AWK程序的工作流程。接下来我们来一起学习一下AWK程序的结构。

  • 开始块(BEGIN block)

顾名思义,开始块就是在程序启动的时候执行的代码部分,并且它在整个过程中只执行一次。一般情况下,我们在开始块中初始化一些变量。BEGIN是AWK的关键字,因此它必须是大写的。不过,开始块部分是可选的,你的程序可以没有开始块部分。

  • 主体块(Body Block)

对于每一个输入的行,都会执行一次主体部分的命令。默认情况下,对于输入的每一行,AWK都会执行命令。注意:在主体块部分,没有关键字存在。

  • 结束块(END Block)

它是在程序结束时执行的代码。END也是AWK的关键字,它也必须大写。与开始块相似,结束块也是可选的。

  • 接下来,我们看一个简单的示例,感知一下AWK的BEGIN块的特性:
     

过程:程序启动时,AWK在开始块中输出表头信息。在主体块中,AWK每读入一行就将读入的内容输出到标准输出流中,一直到整个文件被全部读入为止 

三、awk基本语法

AWK的基本语法如下:

awk [options] ' Pattern{Action} '<file>
  • 对于上面的这个语法,我们先从必选参数action来解释,从字面上理解就是动作,awk擅长文本格式化,并且将格式化以后的文本输出,所以awk中最常用的动作就是print和printf。
  • 先看一些简单的示例,认识一下Action。

下图,我们只是使用awk执行了一个打印的动作,将mytest.txt文件内容的内容给打印出来。

接下来,我们看看类似的一个场景:

下图的awk '{print $5}',表示输出信息的第5列数据,$5表示将当前行按照分隔符分割后的第5列,不指定分隔符时,默认使用空格作为分隔符。当有连续多个空格时,awk自动将连续的空格理解为一个分隔符。 

 Awk是逐行处理的,逐行处理的意思就是说,当awk处理一个文本时,会一行一行进行处理,处理完当前行,再处理下一行,awk默认以“换行符”为标记,识别每一行,也就说,每次遇到“回车换行”,就认为是当前行的结束,新的一行的开始,awk会按照用户指定的分隔符去分割当前行,如果没有指定分隔符,默认使用空格作为分隔符。

 备注:$0和$NF均为内置变量。$NF表示当前行分割后的最后一列。注意:$NF表示最后一个字段,NF表示当前行被分割后,一共有几个字段。那么每行的倒数第二列就可以写成$(NF-1)。

 我们也可以一次输出多个指定的列:

下图,呈现了两种输出方式。特别是:printf中可以格式化输出的字符串,确保输出是等宽字符显示。

 注意:$1这种内置变量的外侧不能加入双引号,否则$1会被当做文本输出

  • 上面我们讲了最常用的语法中的Action:print/printf。现在,我们来认识一下语法中的Pattern,也就是我们说的模式。其实在AWK的工作流程中,我们已经介绍过了两种特殊模式:BEGIN和END。
  • 接下来,我们重点AWK中的普通模式:Pattern,其实就是选择的条件,由于awk是逐行处理文件的,也就是说,AWK会先处理完当前行,再处理下一行,当不指定任何条件,AWK会一行一行的处理文本中的每一行。如果指定了条件,只有满足“条件”的行才会被处理,不满足“条件”的行就不会被处理。
  • 来看一个很简单的示例:使用一个简单的“条件”:如果被处理的行正好有4列字段,那么被处理的行满足“条件”,执行相应的动作。

  • 上面的示例中,我们在模式中,用到了关系的表达式 – 关系操作符。当关系运算符得出的结果为“真”时,则满足条件,表示与指定的模式匹配。
  • 下面来了解一下AWK中的关系运算符:

关系运算符

含义

<<=

小于、小于等于

==!=

等于、不等于

>>=

大于,大于等于

~!~

与对应的正则匹配则为真、与对应的正则不匹配则为真。

  • 上面使用了关系表达式的示例中,其实已经使用了“模式”,这种模式就是“关系表达式模式”,模式被匹配,对应的行就打印输出。
  • 学习到这里,估计有人会问刚开始只有print动作指令,这种称为什么模式呢?-- 空模式: 就是没有使用任何模式,每执行一行都执行了指定的动作。
  • 有人可能会问,既然AWK支持正则表达式,有没有所谓的正则模式呢?答案是有的。
  • 在awk命令中,正则表达式被放入两个斜线中:/正则表达式/。来看这个示例:从/etc/passwd文件中找出以root开头的行。
     

 有时候我们需要在正则中包含“/”,awk中则需要进行转义。

 原因:这是因为正则中包含了“/”,而当使用正则模式时,又需要把正则放入到两个“/”中。所以,需要对“/”进行转义。

行范围模式 – 它表示,从被正则表达式1匹配到的行开始,到被正则表达式2匹配到的行结束,之间的所有行都会执行对应的动作。

备注:行范围模式,它对应的是一个范围以内的所有行,需要注意的是,在行范围模式中,不管是正则表达式1,还是正则表达式2,都是以第一次匹配到的行为准。

基本语法:awk '/正则表达式1/,/正则表达式2/{Action} '<file>

来看这个示例:

接下来,让我们学习一下AWK基本语法中的[Options]可选参数。最常用的是:

  • -F, 用于指定输入分隔符;
  • -v varname=value 变量名区分字符大小写, 用于设置变量的值。

下面通过一些示例来学习一下这两个常用的参数用法:

注意:第二个例子是一个三元表达式的基本用法。在BEGIN块中,变量定义与动作之间需要用分号“;”隔开。 

Awk –F: 指定分隔符。来看一些示例: 

 

备注:FS: Field Separator, 字段分割符,默认是任何空格。OFS: Output Field Separator, 输出记录分隔符。 

内置变量NR与-F结合的示例:NR:Number of Record,已读取的记录数。

四、常用示例

awk if语句:必须用在{}中,且比较内容用()括起来。

列出、统计登录shell为bash的用户:

 统计uid小于等于500和大于500的用户个数:

awk for语句: continue的作用和其它语言类似:跳出“当前”循环。

打印1-10的奇数、偶数序列:

统计家目录下不同用户的普通文件的大小。 

 获取IP地址:

 替换文本文件中的字符串:

 

备注:gsub匹配所有的符合模式的字符串,相当于sed 's//g' 

ØAWK官网文档:https://www.gnu.org/software/gawk/manual/gawk.html 

 AWK程序语言的用法比较复杂,需要参考官网,持续学习,方有提升!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术瘾君子1573

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值