linux基础学习-18.8-awk特殊模式-BEGIN模式与END模式

BEGIN模块再awk读取文件之前就执行,一般用来定义我们的内置变量(预定义变量,eg:FS,RS),可以输出表头(类似excel表格名称)

BEGIN模式之前我们有在示例中提到,自定义变量,给内容变量赋值等,都使用过。需要注意的是BEGIN模式后面要接跟一个action操作块,包含在大括号内。awk必须在输入文件进行任何处理前先执行BEGIN里的动作(action)。我们可以不要任何输入文件,就可以对BEGIN模块进行测试,因为awk需要先执行完BEGIN模式,才对输入文件做处理。BEGIN模式常常被用来修改内置变量ORS,RS,FS,OFS等值。

1、BEGIN模块

1)第一个作用,内置变量的定义

例1:取eth0的IP地址

[root@www files]# ifconfig eth0|awk -F "(addr:)|( Bcast:)" 'NR==2{print $2}'
192.168.197.133 
[root@www files]# ifconfig eth0 | awk -F "[ :]+" 'NR==2{print $4}'
192.168.197.133
[root@www files]# ifconfig eth0 | awk -F "[^0-9.]+" 'NR==2{print $2}'
192.168.197.133

#上面的也可以写成

[root@www files]# ifconfig eth0 | awk 'BEGIN{FS="(addr:)|( Bcast:)"} NR==2{print $2}'
192.168.197.133 
[root@www files]# ifconfig eth0 | awk 'BEGIN{FS="[ :]+"}NR==2{print $4}'
192.168.197.133
[root@www files]# ifconfig eth0 | awk 'BEGIN{FS="[^0-9.]+"}NR==2{print $2}'
192.168.197.133

注意:

命令行-F本质就是修改的FS变量

2)第二个作用,在读取文件之前,输出些提示性信息(表头)。

[root@www files]# awk -F: 'BEGIN{print "username","UID"}{print $1,$3}' awkfile.txt 
username UID   #这就是输出的表头信息
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
uucp 10

说明:

要在第一行输出一些username和UID,我们应该想到BEGIN{}这个特殊的条件(模式),因为BEGIN{}在awk读取文件之前执行的。

所以结果是BEGIN{print "username","UID"},注意print命令里面双引号吃啥吐啥,原样输出。

然后我们实现了在输出文件内容之前输出“username”和“UID”,下一步输出文件的第一列和第三列即{print $1,$3}

最后结果就是BEGIN{print "username","UID"}{print $1,$3}

3)第三个作用,使用BEGIN模块的特殊性质,进行一些测试。

[root@www files]#简单输出内容:
[root@www files]# awk 'BEGIN{print "hello world!"}'
hello world!
[root@www files]# #进行计算
[root@www files]# awk 'BEGIN{print 10/3}'
3.33333
[root@www files]# awk 'BEGIN{print 10/3+1}'
4.33333
[root@www files]# awk 'BEGIN{print 10/3+1/4*9}'
5.58333
[root@www files]# #和变量有关的操作
[root@www files]# awk 'BEGIN{a=1;b=2;print a,b}'
1 2
[root@www files]# awk 'BEGIN{a=1;b=2;print a,b,a+b}'
1 2 3

4)第四种用法:配合getline读取文件,后面awk函数处讲解

2、awk中变量的概念简介

直接定义,直接使用即可

awk中字母会被认为是变量,如果真的要给一个变量赋值字母(字符串),请使用双引号

[root@oldboy files]# awk 'BEGIN{a=abcd;print a}'
[root@oldboy files]# awk 'BEGIN{abcd=123456;a=abcd;print a}'
123456
[root@oldboy files]# awk 'BEGIN{a="abcd";print a}'
abcd

说明:

没有文件awk依旧可以处理BEGIN模式下的动作(命令)

3、END模块

EHD在awk读取完所有的文件的时候,再执行END模块,一般用来输出一个结果(累加,数组结果),也可以是和BEGIN模块类似的结尾标识信息

[root@oldboy files]# awk 'BEGIN{print "hello world!"}{print NR,$0}END{print "end of file"}' count.txt 
hello world!
1 root x root root bin bash
2 bin x bin bin sbin nologin
3 daemon x daemon sbin sbin nologin
4 adm x adm var adm sbin nologin
5 lp x lp var spool lpd sbin nologin
6 sync x sync sbin bin sync
7 shutdown x shutdown sbin sbin shutdown
8 halt x halt sbin sbin halt
9 mail x mail var spool mail sbin nologin
10 uucp x uucp var spool uucp sbin nologin
end of file

与BEGIN模式相对应的END模式,格式一样,但是END模式仅在awk处理完所有输入行后才进行处理。

企业案例:统计/etc/servies文件里的空行数量

思路:

a)空行通过正则表达式来实现:^$

b)统计数量:

grep -c

awk

方法一:grep

[root@oldboy files]# grep "^$" /etc/services | wc -l
16
[root@oldboy files]# grep -c "^$" /etc/services
16

说明:

grep命令-c表示count计数统计包含^$的行一共有多少。

方法二:

[root@oldboy files]# awk '/^$/{i++}END{print i}' /etc/services 
16

提示:

使用了awk的技术功能,很常用

第一步:统计空行个数

/^$/表示条件,匹配出空行,然后执行{i++}(i++等于i=i+1)即:/^$/{i=i+1}

我们可以通过/^$/{i=i+1;print i}来查看awk执行过程

[root@oldboy files]# awk '/^$/{i=i+1;print "the value of i is:"i}' /etc/services 
the value of i is:1
the value of i is:2
the value of i is:3
the value of i is:4
the value of i is:5
the value of i is:6
the value of i is:7
the value of i is:8
the value of i is:9
the value of i is:10
the value of i is:11
the value of i is:12
the value of i is:13
the value of i is:14
the value of i is:15
the value of i is:16

第二步:输出最后结果

但是我们只想要最后的结果16,不想要过程怎么办?使用END模式输出结果

因为END模式的特殊性质所以很适合输出最终结果

所以最终结果就是awk '/^$/{i=i+1}END{print "blank lines count:"i}' /etc/services

awk编程思想:

先处理,最后再END模块输出

{print NR,$0}body模块处理,处理完毕后

END{print "end of file"}输出一个结果

企业面试题:文件count.txt,文件内容是1到100(由seq 100生成),请计算文件每行值加起来的结果(计算1+...+100)

思路:

文件每一行都有且只有一个数字,所以我们要让文件的每行内容相加。

回顾一下上一道题我们用的是i++即i=i+1

这里我们需要使用到第二个常用的表达式

i=i+$0

对比一下,其实只是把上边的1换成了$0

[root@oldboy files]# awk '{i=i+$0}END{print i}' count.txt

5050

练习题:

1、取eth0的IP地址(BEGIN模块)

2、统计/etc/servies文件里的空行数量

3、BEGIN模块的三个作用

原文地址:https://www.cnblogs.com/Klanti/p/9143701.html