作用:awk可以完成复杂的数据分析,如日志分析等等。
1. awk概述
awk不仅仅是Linux系统中的一个命令,更可以理解为它是一种编程语言,可以用来处理数据和生成报告(excel)。处理的数据可以是一个或多个文件,可以是来自标准输入,也可以通过管道获取标准输入,awk可以在命令行上直接编辑命令进行操作,也可以编写成awk程序来进行更为复杂的运用。本章主要讲解awk命令的运用。
2. awk格式
awk指令是由模式,动作,或者模式和动作的组合组成。
模式既pattern,可以类似理解成sed的模式匹配,可以由表达式组成,也可以是两个正斜杠之间的正则表达式。比如NR==1,这就是模式,可以把他理解为一个条件。
动作即action,是由在大括号里面的一条或多条语句组成,语句之间使用分号隔开。

awk处理的内容可以来自标准输入(<),一个或多个文本文件或管道。

options既参数,使用最多的参数为-F(Field,用于指定字段与字段之间的分隔符,列与列之间的分隔符,默认为空格)
pattern既模式,也可以理解为条件,也叫找谁,你找谁?高矮,胖瘦,男女?都是条件,既模式。
action既动作,可以理解为干啥,找到人之后你要做什么。
注意:awk -F"分隔符" '模式和动作' file
-F后面跟是双引号,模式和动作要使用单引号进行包裹!!!
模式和动作的详细介绍我们放在后面部分,现在大家先对awk结构有一个了解。
案例1:基本模式与动作
# awk -F ":" 'NR>=2 && NR<=6{print NR,$1}' /etc/passwd
2 bin
3 daemon
4 adm
5 lp
6 sync
命令说明:
-F 指定分隔符为冒号,相当于以“:”为菜刀,进行字段的切割。
NR>=2 && NR<=6:这部分表示模式,是一个条件,表示取第2行到第6行。
{print NR,$1}:这部分表示动作,表示要输出NR行号和$1第一列。
$1代表第1列
$2代表第2列
依次类推
NR == Number(数字、号码)+ Record(记录、行)== 行号
案例2:只有模式
# awk -F ":" 'NR>=2 && NR<=6' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
命令说明:
-F指定分隔符为冒号
NR>=2&&NR<=6这部分是条件,表示取第2行到第6行。
但是这里没有动作,这里大家需要了解如果只有条件(模式)没有动作,awk默认输出整行
案例3:只有动作
awk如果不指定模式,代表获取这个文件的所有行,因为awk默认也是按行处理!
# awk -F ":" '{print NR,$1}' /etc/passwd
1 root
2 bin
3 daemon
4 adm
5 lp
6 sync
7 shutdown
8 halt
9 mail
10 uucp
以下省略....
命令说明:
-F指定分隔符为冒号
这里没有条件,表示对每一行都处理
{print NR,$1}表示动作,显示NR行号与$1第一列
这里要理解没有条件的时候,awk会处理每一行。
案例4:多模式与多动作
# awk -F ":" 'NR==1{print NR,$1}NR==2{print NR,$NF}' /etc/passwd
1 root
2 /sbin/nologin
命令说明:
-F指定分隔符为冒号
这里有多个条件与动作的组合
NR==1表示条件,行号(NR)等于1的条件满足的时候,执行{print NR,$1}动作,输出行号与第一列。
NR==2表示条件,行号(NR)等于2的条件满足的时候,执行{print NR,$NF}动作,输出行号与最后一列($NF)
NR:Number Record,行号信息
NF:Number Field,列号信息,注意:计数情况下,$NF代表最后一列
注意:
Pattern和{Action}需要用单引号引起来,防止Shell作解释。
Pattern是可选的。如果不指定,awk将处理输入文件中的所有记录。如果指定一个模式,awk则只处理匹配指定的模式的记录。
{Action}为awk命令,可以是但个命令,也可以多个命令。整个Action(包括里面的所有命令)都必须放在{ 和 }之间。
Action必须被{ }包裹,没有被{ }包裹的就是Pattern
file要处理的目标文件
3. awk执行过程
在深入了解awk前,我们需要知道awk如何处理文件的。
# mkdir /server/files/ -p
# head /etc/passwd > /server/files/awkfile.txt
# cat /server/files/awkfile.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
awk执行过程演示:
# awk 'NR>=2{print $0}' /server/files/awkfile.txt
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
命令说明:
条件NR>=2,表示行号大于等于2时候,执行{print $0}显示整行。
awk是通过一行一行的处理文件,这条命令中包含模式部分(条件)和动作部分(动作),awk将处理模式(条件)指定的行
$0代表所有列,$1代表第1列,$2代表第2列,... $NF代表最后1列
awk执行过程解析:
① awk读入第一行内容
② 判断是否符合模式中的条件NR>=2
如果匹配则执行对应的动作{print $0}
如果不匹配条件,继续读取下一行
③ 继续读取下一行
④ 重复过程1-3,直到读取到最后一行(EOF:end of file)

4. awk记录(行)
awk特别适合处理有行有列的二维结构
记录和字段 接下来我给大家带来两个新概念记录和字段,这里为了方便大家理解可以把记录就当作行即记录==行,字段相当于列,字段==列。
| 名称 | 含义 |
| record | 记录,行 => NR(Number Record)行号 |
| field | 域,区域,字段,列 => NF(Number Field)列号,$NF代表最后一列 |
数据集:
# cat /server/files/awkfile.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
思考:
一共有多少行呢?你如何知道的?通过什么标志?
awk对每个要处理的输入数据认为都是具有格式和结构的,而不仅仅是一堆字符串。默认情况下,每一行内容都是一条记录,并以换行符分隔(\n)结束。

awk默认情况下每一行都是一个记录(record)
① RS既record separator输入输出数据记录分隔符,每一行是怎么没的,表示每个记录输入的时候的分隔符,既行与行之间如何分隔,默认为\n,可以调整为其他字符。
② NR既number of record 记录(行)号,表示当前正在处理的记录(行)的号码。
③ ORS既output record separator 输出记录分隔符。
awk使用内置变量RS来存放输入记录(行与行)分隔符,RS表示的是输入的记录分隔符,这个值可以通过BEGIN模块重新定义修改。
案例1:
# awk 'BEGIN{RS="/"}{print NR,$0}' /server/files/awkfile.txt
1 root:x:0:0:root:
2 root:
3 bin
4 bash
bin:x:1:1:bin:
5 bin:
6 sbin
7 nologin
daemon:x:2:2:daemon:
8 sbin:
9 sbin
10 nologin
adm:x:3:4:adm:
11 var
12 adm:
13 sbin
14 nologin
lp:x:4:7:lp:
15 var
16 spool
17 lpd:
18 sbin
19 nologin
sync:x:5:0:sync:
20 sbin:
21 bin
22 sync
shutdown:x:6:0:shutdown:
23 sbin:
24 sbin
25 shutdown
halt:x:7:0:halt:
26 sbin:
27 sbin
28 halt
mail:x:8:12:mail:
29 var
30 spool
31 mail:
32 sbin
33 nologin
uucp:x:10:14:uucp:
34 var
35 spool
36 uucp:
37 sbin
38 nologin
命令说明:
BEGIN:开始模块,在awk开始处理数据之前执行1次
END:结束模块,在awk处理所有行后执行1次
在每行的开始先打印输出NR(记录号行号),并打印出每一行$0(整行)的内容。
我们设置RS(记录分隔符)的值为“/”,表示一行(记录)以“/”结束
在awk眼中,文件是从头到尾一段连续的字符串,恰巧中间有些\n(回车换行符),\n也是字符哦。
我们回顾下“行(记录)”到底是什么意思?
行(记录):默认以\n(回车换行)结束。而这个行的结束不就是记录分隔符嘛。
所以在awk中,RS(记录分隔符)变量表示着行的结束符号(默认是回车换行)
在工作中,我们可以通过修改RS变量的值来决定行的结束标志,最终来决定“每行”的内容。
为了方便人们理解,awk默认就把RS的值设置为“\n”
注意:
awk的BEGIN模块,我会在后面(模式-BEGIN模块)详细讲解,此处大家仅需要知道在BEGIN模块里面我们来定义一些awk内置变量即可。
对$0的认识
awk '{print NR,$$NF,$$0,$$1,$$2,...}'
NR:行号,打印行号
NF:NF代表列号,如果前面添加了,则代表最后一列
$0:整行内容
1:按照-F分割后,1代表分割后的第1列
2:按照-F分割后,2代表分割后的第2列
由以上代码运行可知:awk中$$0表示整行,其实awk使用$$0来表示整条记录。记录分隔符存在RS变量中或者说每个记录以RS内置变量结束。
另外,awk对每一行的记录号都有一个内置变量NR来保存,每处理完一条记录,NR的值就会自动+1
案例2:NR记录行号
# awk '{print NR,$0}' /server/files/awkfile.txt
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
命令说明:
NR既number of record,当前记录的记录号,刚开始学也可以理解为行号。
$0表示整行或者说整个记录
企业面试题:按单词出现频率降序排序(计算文件中每个单词的重复数量)
sed -r '1,10s#[^a-zA-Z]+# #g' /etc/passwd |head > /server/files/count.txt
# cat /server/files/count.txt
root x root root bin bash
bin x bin bin sbin nologin
daemon x daemon sbin sbin nologin
adm x adm var adm sbin nologin
lp x lp var spool lpd sbin nologin
sync x sync sbin bin sync
shutdown x shutdown sbin sbin shutdown
halt x halt sbin sbin halt
mail x mail var spool mail sbin nologin
uucp x uucp var spool uucp sbin nologin
思路:
让所有单词排成一列,这样每个单词都是单独的一行
① 设置RS值为空格
② 将文件里面的所有空格替换为回车换行符“\n”
③ 基于sort + uniq -c实现词频统计
方案一:
# awk 'BEGIN{RS="[ ]+"}{print $0}' /server/files/count.txt |grep -Ev '^$' |sort |uniq -c |sort -nr
效果图:

方案二:
# cat count.txt | tr " " "\n" | sort | uniq -c | sort -nr
小结:
以后遇到词频统计,大致处理流程都是一样的:① 想办法把每个单词单独放一行 ② sort + uniq -c ③ 最后在升序或降序
5. awk字段(列)
每条记录都是由多个区域(field)组成的,默认情况下区域之间的分隔符是由空格(即空格或制表符)来分隔,并且将分隔符记录在内置变量FS中,每行记录的区域数保存在awk的内置变量NF中。
a b c d

FS既field separator,输入字段(列)分隔符。分隔符就是菜刀,把一行字符串切为很多个区域。
NF既number of fileds,表示一行中列(字段)的个数,可以理解为菜刀切过一行后,切成了多少份。
OFS输出字段(列)分隔符
① awk使用内置变量FS来记录区域分隔符的内容,FS可以在命令行上通过-F参数来更改,也可以通过BEGIN模块来更改。
② 然后通过n,n是整数,来取被切割后的区域,1取第一个区域,2取第二个区域,NF取最后一个区域。
案例1:指定分隔符
# awk -F ":" 'NR>=2&&NR<=5{print $1,$3}' /server/files/awkfile.txt
bin 1
daemon 2
adm 3
lp 4
命令说明:
以:(冒号)为分隔符,显示第2行到第5行之间的第一区域和第三区域。
案例2:提取字符串中的内容
# echo "I am eric,my qq is 1234567890" >> /server/files/test.txt
# cat /server/files/test.txt
I am eric,my qq is 1234567890
思路:
我们用默认的想法一次使用一把刀,需要配合管道的。如何同时使用两把刀呢?看下面的结果
# awk -F "[ ,]" '{print $3,$NF}' /server/files/test.txt
eric 1234567890
命令说明:
通过命令-F参数指定区域分隔符
[ ,]是正则表达式里面的内容,它表示一个整体,“一个”字符,既空格或者逗号(,),合并在一起,-F “[ ,]”就表示以空格或者逗号(,)为区域分隔符
小技巧:
在动作({print $3,$NF})里面的逗号,表示空格,其实动作中的逗号就是OFS的值,我们会在后面说明。刚开始大家把动作中的都逗号,当作空格即可。
6. awk分隔符
# vim /server/files/awkblank.txt
inet addr:192.168.197.133 Bcast:192.168.197.255 Mask:255.255.255.0
#默认分隔符时候(按空格进行分割)
# awk '{print $1}' /server/files/awkblank.txt
inet
说明:如果采用默认分隔符,切割内容,如果左边有一大批空白内容,则默认分隔符会自动忽略此内容。
#指定分隔符时候(人为指定分隔符)
# awk -F "[ :]+" '{print $1}' /server/files/awkblank.txt
# awk -F "[ :]+" '{print $2}' /server/files/awkblank.txt
inet
说明:如果采用人为设定分隔符,切割内容,如果左边有一大批空白内容,则人为设定的分隔符会对这块内容进行切割。
命令说明:
awk默认的FS分隔符对于空格序列,一个空格或多个空格tab都认为是一样的,一个整体。
正常情况下,切割后,数据都是从$1开始
但是如果一个文件的开头有很多连续的空格,然后才是inet这个字符
当我们使用默认的分隔符的时候,$1是有内容
当我们指定其他分隔符(非空格)时候,区域会有所变化,$2才有内容
7. awk模式与动作进阶
awk模式与动作
接下来就详细介绍下,awk的模式都有几种:
☆ 正则表达式作为模式
☆ 比较表达式作为模式 NR>=2
☆ 范围模式 NR>=2 && NR <= 5
☆ 特殊模式BEGIN和END
案例1:awk正则表达式匹配整行
sed '/正则表达式/'
awk '/正则表达式/'
awk '$0~/正则表达式/',$0代表整行,~波浪线后面根的就是/正则表达式/
# awk -F ":" '/^root/' awkfile.txt
或
# awk -F ":" '$0~/^root/' awkfile.txt
命令解析:
awk只用正则表达式的时候是默认匹配整行的即‘$0~/root/’和‘/root/’是一样的。
案例2:awk正则表达式匹配一行中的某一列
# awk -F ":" '$5~/shutdown/' awkfile.txt
命令解析:
$5表示第五个区域(列)
~表示匹配(正则表达式匹配)
/shutdown/表示匹配shutdown这个字符串
合在一起,$5~/shutdown/表示第五个区域(列)匹配正则表达式/shutdown/,既第5列包含shutdown这个字符串,则显示这一行。
案例3:某个区域中的开头和结尾
知道了如何使用正则表达式匹配操作符之后,我们来看看awk正则与grep和sed不同的地方。
awk正则表达式:
| ^ | 匹配一个字符串的开头 |
| $ | 匹配一个字符串的结尾 |
数据集
# cat >>/server/files/reg.txt<<KOF
Zhang Dandan 41117397 :250:100:175
Zhao Xiaoyu 390320151 :155:90:201
Meng Feixue 80042789 :250:60:50
Wu Yujia 70271111 :250:80:75
Liu Bingbing 41117483 :250:100:175
Wang Yangming 3515064655 :50:95:135
Guan Tingting 1986787350 :250:168:200
Li Xinxin 918391635 :175:75:300
Liao Feifan 918391635 :250:100:175
KOF
说明:
第一列是姓氏
第二列是名字
第一列第二列合起来就是姓名
第三列是对应的ID号码
最后三列是三次捐款数量
练习题1:显示姓Zhang的人的第二次捐款金额及她的名字
# awk -F "[ :]+" '$1~/^Zhang/{print $2,$(NF-1)}' reg.txt
练习题2:显示Xiaoyu的名字和ID号码,并以逗号隔开
# awk -F "[ :]+" '$2~/^Xiaoyu$/{print $2","$3}' reg.txt
注意:
如果{print $2,$3},则两者默认是按空格隔开的
如果{print $2","$3},则两者使用逗号隔开
练习题3:显示所有以41开头的ID号码的人的全名和ID号码
# awk -F "[ :]+" '$3~/^(41)/{print $1,$2,$3}' reg.txt
练习题4:显示所有以一个D或X开头的人名全名
# awk -F "[ :]+" '$2~/^D|^X/{print $1,$2}' reg.txt
练习题5:显示所有ID号码最后一位数字是1或5的人的全名
# awk -F "[ :]+" '$3~/1$|5$/{print $1,$2}' reg.txt
案例4:取出网卡ens33/ens160的ip地址
VMware16 => ens33
VMware17 => ens160
网卡 => eth0
最简单:hostname -I
ifconfig ens33 |sed -n '2p' |awk -F"[ ]+" '{print $3}'
或
ifconfig ens160 |sed -n '2p' |awk -F"[ ]+" '{print $3}'
案例5:取出常用服务端口号(面试) 思路: linux下面服务与端口信息的对应表格在/etc/services里面,所以这道题要处理/etc/services文件
# sed -n '23,30p' /etc/services
tcpmux 1/tcp # TCP port service multiplexer
tcpmux 1/udp # TCP port service multiplexer
rje 5/tcp # Remote Job Entry
rje 5/udp # Remote Job Entry
echo 7/tcp
echo 7/udp
discard 9/tcp sink null
discard 9/udp sink null
从23行开始基本上每一行第一列是服务名称,第二列的第一部分是端口号,第二列的第二部分是tcp或udp协议。
# awk -F "[ /]+" '$1~/^(ssh)$|^(http)$|^(https)$|^(mysql)$|^(ftp)$/{print $1,$2}' /etc/services |sort|uniq
ftp 21
http 80
https 443
mysql 3306
ssh 22
命令解析:
|是或者的意思,正则表达式
sort是将输出结果排序
uniq是去重复但不标记重复个数
uniq -c去重复但标记重复个数
8. BEGIN模式与END模式

☆ BEGIN模式
BEGIN模块在awk读取文件之前就执行,一般用来定义我们的内置变量(预定义变量,eg:FS,RS),可以输出表头(类似excel表格名称)
BEGIN模式之前我们有在示例中提到,自定义变量,给内容变量赋值等,都使用过。需要注意的是BEGIN模式后面要接跟一个action操作块,包含在大括号内。awk必须在输入文件进行任何处理前先执行BEGIN里的动作(action)。我们可以不要任何输入文件,就可以对BEGIN模块进行测试,因为awk需要先执行完BEGIN模式,才对输入文件做处理。BEGIN模式常常被用来修改内置变量ORS,RS,FS,OFS等值。
案例1:可以使用BEGIN设定表头信息
BEGIN模块完整写法:BEGIN{}
# 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}
案例2:awk还可以指定RS,行与行之间分隔符
# awk 'BEGIN{RS="/"}{print NR,$0}' /server/files/awkfile.txt
1 root:x:0:0:root:
2 root:
3 bin
4 bash
bin:x:1:1:bin:
5 bin:
6 sbin
7 nologin
案例3:awk变量
直接定义,直接使用即可
awk命令不仅可以进行数据获取分析,还支持数学运算!
awk中字母会被认为是变量,如果真的要给一个变量赋值字母(字符串),请使用双引号
# awk 'BEGIN{a=abcd;print a}'
# awk 'BEGIN{abcd=123456;a=abcd;print a}'
123456
# awk 'BEGIN{a="abcd";print a}'
abcd
小结:① 输出表头 ② 指定RS行与行之间分隔符 ③ awk本身支持数学计算,我们还可以使用BEGIN初始化变量!
☆ END模式
作用:与BEGIN相呼应,在awk处理文件结束后,会自动触发END模块(只会触发1次)
基本语法:
awk '动作 END{print xxx}'
应用场景说明: awk执行结束,用于实现收尾操作 ① 数学计算中,输出最终结果 ② 输出最后一行等等
案例1:统计/etc/servies文件里的空行数量
思路:
a) 空行通过正则表达式来实现:^$,grep中直接写,sed/awk中使用正则必须使用/正则表达式/
b) 统计数量:wc -l,grep -c,还可以使用awk数学计算
grep方法:
# grep "^$" /etc/services | wc -l
16
# grep -c "^$" /etc/services
16
说明:
grep命令-c表示count计数统计包含^$的行一共有多少。
awk方法:
awk '/^$/' /etc/services |wc -l
或
awk 'BEGIN{i=0}; /^$/{i=i+1};END{print "blank lines count:"i}' /etc/services
或
awk '/^$/{i=i+1};END{print "blank lines count:"i}' /etc/services
注意:在awk中,如果进行计算时,需要变量初始化为0,其实不需要通过BEGIN指定,因为默认变量都是0
提示:
使用了awk的技术功能,很常用
第一步:统计空行个数
/^$/表示条件,匹配出空行,然后执行{i++}(i++等于i=i+1)即:/^$/{i=i+1}
我们可以通过/^$/{i=i+1;print i}来查看awk执行过程
第二步:
awk编程思想:
先处理,最后再END模块输出
{print NR,$0}body模块处理,处理完毕后
END{print "end of file"}输出一个结果
案例2:awk支持数学运算
awk数学运算,awk数学运算,既支持整数运算,也支持小数运算
echo "1 + 1.5" |bc
echo | awk '{print 1+2}'
echo | awk '{print 1+1.5}'
案例3:文件count.txt,文件内容是1到100(由seq 100生成),请计算文件每行值加起来的结果(计算1+...+100)
思路:
文件每一行都有且只有一个数字,所以我们要让文件的每行内容相加。
回顾一下上一道题我们用的是i++即i=i+1
这里我们需要使用到第二个常用的表达式
i=i+$0
对比一下,其实只是把上边的1换成了$0
# awk '{i=i+$0}END{print i}' count.txt
面试题:在awk中,我们可以使用$1取出第1列,$NF取出最后1列,NR==1代表第1行,问awk如何取出最后一行?
tail -1 /server/files/awkfile.txt
或
awk 'END{print $0}' /server/files/awkfile.txt
复习:
基本语法:awk -F"分隔符" '模式{动作}' 文件
-F:可以普通字符,如逗号、空格、横岗等等;还可以是正则表达式-F "[ ,]+"
模式:
① 指定行,NR==5,NR >= 3 && NR <= 6
② 条件,$1 >= 18,第1列中,如果值大于等于18,则显示对应的整行内容
③ 正则表达式 => /正则表达式/ => '/正则表达式/{xxx}',如'$1~/0-9/'
动作:
{print $1,$2,$NF},$1第1列,$2第2列,$NF最后1列
{print 100-$8},awk本身支持数学计算
BEGIN/END模块
awk 'BEGIN{RS="/"}',把行与行之间分隔符,设置为/左斜杠
awk 'NR==1{print $0}',输出第一行
awk 'END{print $0}',输出最后一行,把计算的几个案例写写
注意:BEGIN在awk处理之前执行,END在awk处理之后执行。而且他们都只会执行1次!!!