【shell编程】awk语法
正文
awk语法简介
是一个文本处理工具,用于逐行处理文本文件,任何awk语句都是由模式和动作组成,一个awk脚本可以有多个语句,模式决定动作语句的触发条件和触发时间。
1. 模式包含:正则表达式,/[正则表达式]/;关系运算符,<、<=、>、>=、!=、==;正则运算符,~(匹配)、!~(不匹配);赋值运算符,=、+=、-=、*=、/=、%=、**=;逻辑运算符||、&&;算术运算符+、-、*、/、++、--;其他运算符,$(用来对字段进行引用),空格(字符串连接符)。
2. 动作包含:变量、命令、内置函数、流程控制语句。
3. 语法:awk [选项] 'BEGIN{开始语句} 模式{动作} END{结束语句}' [文件]
其中BEGIN和END是awk的关键字,必须大写。不过开始模块和结束模块是可选部分,可以省略。并且开始语句和结束语句也是动作语句。另外,工作模块中的模式和动作可以都存在,也可以二者选其一。
- 如果省略模式,那么文件的所有行都执行动作;
- 如果省略动作,表示对符合条件的行执行默认的print动作。正因为可以二者选其一,所以一般用{}包裹动作,用于区分模式和动作。
1. 特殊模块BEGIN和END
在awk中BEGIN和END都只能执行一次。BEGIN语句在动作语句之前执行,一般用于设置变量计数的起始值,打印头部信息和改变字段的分隔符。END语句在完成动作语句之后执行,一般用于输出统计结果,打印结尾信息。
2. awk的执行过程(工作步骤)分为五个步骤:
- 第一步,执行BRGIN模块;
- 第二步,从文件、管道或标准输入中读取一行保存到内存中;
- 第三步,对读取的行数据执行工作模块;
- 第四步,判断是否到达文件、管道或标准输入的结尾,如果未到达结尾则重复第二步和第三步;
- 第五步,到达文件、管道或标准输入的结尾后,执行END模块。
图示执行过程如下:
[root@creditease awk]# awk '{a[$1]=a[$1]+$2}END{for(i in a)print i,a[i]}' jia.txt
a 4
b 8
c 2
d 7
f 6
g 2
命令 awk '{b[$1]=b[$1]+$2}END{for(i in b)print i,b[i]}' jia.txt
使用了 AWK 工具来处理 jia.txt
文件的内容。让我们逐步解释这个命令:
-
{b[$1]=b[$1]+$2}
:- 这部分命令使用了 AWK 的数组和循环功能。在 AWK 中,
b
是一个关联数组,$1
和$2
分别代表当前处理行的第一个和第二个字段。 b[$1]
表示以第一个字段$1
的值作为索引,存储在数组b
中。b[$1]=b[$1]+$2
的意思是,如果数组b
中已经有$1
这个索引,就将当前行的第二个字段$2
的值加到b[$1]
中去;如果b[$1]
还未定义,则会被初始化为0
,然后加上$2
的值。- 因此,对于每一行,这个命令都会根据第一个字段的值
$1
来累加第二个字段$2
的值到数组b
的相应元素中。
- 这部分命令使用了 AWK 的数组和循环功能。在 AWK 中,
-
END{for(i in b)print i,b[i]}
:END{}
部分是 AWK 中的特殊块,在处理完所有行之后执行。for(i in b)
循环遍历数组b
的所有索引i
。print i, b[i]
打印每个索引i
及其对应的值b[i]
,即每个字母和其累加后的数字总和。
解释 $1=a
时的情况:
当执行到 awk '{b[$1]=b[$1]+$2}END{for(i in b)print i,b[i]}' jia.txt
并且当前处理的行中 $1=a
时:
- 初始时
b[$1]
是未定义的,即b[a]
未初始化。 b[$1]=b[$1]+$2
中的b[a]
在第一次碰到a
时会被初始化为0
,然后加上当前行的$2
的值。
举例来说,假设当前行是 a 1
:
- 初始时
b[a]
未定义,所以b[a]
被初始化为0
。 - 执行
b[a]=b[a]+$2
,即b[a]=0+1
,所以现在b[a]=1
。
如果后续又碰到了 a 3
:
- 现在
b[a]
已经是1
。 - 执行
b[a]=b[a]+$2
,即b[a]=1+3
,所以现在b[a]=4
。
对一个文件名为qc.txt的文件进行去重处理,内容如下:
2018/10/20 xiaoli 13373305025
2018/10/25 xiaowang 17712215986
2018/11/01 xiaoliu 18615517895
2018/11/12 xiaoli 13373305025
2018/11/19 xiaozhao 15512013263
2018/11/26 xiaoliu 18615517895
2018/12/01 xiaoma 16965564525
2018/12/09 xiaowang 17712215986
2018/11/24 xiaozhao 15512013263
实行命令:
# awk '!a[$2]++' qc.txt
说明:执行命令 awk '!a[$2]++' qc.txt
的作用是去除文件 qc.txt
中每个记录中第二列重复的行,只保留第一次出现的行。让我们来详细解释这个命令的执行过程和结果。
-
!a[$2]++
解释:a[$2]
表示以第二列$2
的值作为索引,将其存储在数组a
中。!a[$2]
的逻辑是:如果a[$2]
为假(即未定义或者为零),则取反后为真。a[$2]++
表示对a[$2]
的值进行自增操作,但是在自增之前使用了后缀自增运算符++
,所以实际上!a[$2]++
是在判断a[$2]
的值,并在判断后自增。
-
操作过程:
- 对于每一行,在判断
!a[$2]++
时,如果a[$2]
尚未被设置(即第一次出现),!a[$2]
将为真,条件成立。 - 所以,条件成立时,当前行会被输出(默认操作是打印整行)。
- 同时,
a[$2]
会被设置为非零值,因为后缀自增操作符++
会使a[$2]
的值自增。
- 对于每一行,在判断
-
输出结果:
- 命令的输出是处理后的文件内容,只保留了第二列(即联系人姓名)第一次出现的行。
- 因此,输出结果是去除了重复联系人姓名的行,保留了每个联系人姓名第一次出现的行。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2021-05-23 【docker】docker安装与卸载