周顺的技术博客

  • 1. awk概述
  • 2. awk格式
  • 3. awk执行过程
  • 4. awk记录(行)
  • 5. awk字段(列)
  • 6. awk分隔符
  • 7. awk模式与动作进阶
  • 8. BEGIN模式与END模式
  • 首页
  • 榜上有名
  • 文章归档
  • 读者排行
  • 豆瓣书影
  • 友情链接
  • DevOps (4)
  • Docker (4)
  • k8s (9)
  • linux (11)
  • Mysql (9)
  • Python (2)
  • Redis (1)
  • Shell (6)
  • 主题 (0)
  • 未分类 (0)

Shell三剑客之awk指令

  • xiaoteng
  • 2026-05-11
  • 2

作用: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次!!!

© 2026 周顺的技术博客
Theme by Wing
  • {{ item.name }}
  • {{ item.name }}