目录
4.awk【擅长对列进行操作并进行处理】
4.1 格式说明
awk命令也是逐行扫描文件(从第一行到最后一行),寻找含有目标文本的行,如果匹配成功,则会在该行上执行用户想要的操作;反之,则不对行做任何处理
简介:常用来做列数据切分与提取(最擅长取列)
语法:
awk [选项] '脚本命令' 文件名
awk [选项] '匹配规则{执行命令}' 文件名
语法解释:
- '匹配规则':表示从哪个地方开始执行,如:1,3表示第1行到第3行;或者写出发时间:BEGIN、END
- 整个'脚本命令'是用单引号' ' 括起,而其中的 '执行命令' 部分需要用大括号{ }
- 如果没有指定 '执行命令' 则默认会把匹配的行输出;如果不指定 '匹配规则',则默认匹配文本中所有的行
选项 含义 -F fs 指定以 fs 作为输入行的分隔符,awk 命令默认分隔符为空格或制表符。 -f file 从脚本文件中读取 awk 脚本指令,以取代直接在命令行中输入指令。 -v
var=val
在执行处理过程之前,设置一个变量 var,并给其设备初始值为 val。
4.2 awk字段变量
awk 的主要特性之一是其处理文本文件中数据的能力,awk 在读取一行文本时会用预定义的字段分隔符划分每个数据字段。它会自动给一行中的每个数据元素分配一个变量。
默认情况下,awk 会将行按指定要求切割后分配如下变量:
- $0 代表整个文本行;
- $1 代表文本行中的第 1 个数据字段;
- $2 代表文本行中的第 2 个数据字段;
- $n 代表文本行中的第 n 个数据字段。
在awk中,默认的字段分隔符是任意的空白符号
4.3 查询信息
实验环境:
[root@hero ~]# cat /oldboy/oldboy.txt
01 oldboy 15612422861 sa 15000;15000;2000
02 oldgirl 18845678923 db 20000;20000;2000
03 oldbaby 17778953645 dev 18000;12000;3000
04 olddog 18956423145 CTO 50000;50000;5000
05 oldboy oldgirl oldbaby olddog
06 oldgirl oldboy oldbaby olddog
根据文件内容查询指定行信息
# 查询oldboy.txt文件中含有'oldboy'的行
[root@hero ~]# awk '/oldboy/' /oldboy/oldboy.txt
01 oldboy 15612422861 sa 15000;15000;2000
根据文件行号查询指定行信息
# 查询oldboy.txt文件的第4行信息
[root@hero ~]# awk "NR==4" /oldboy/oldboy.txt
04 olddog 18956423145 CTO 50000;50000;5000
显示出指定行中的指定列信息
# 查询oldboy.txt文件中含有oldboy哪一行的第2列和第5列
# ,==" " 表示空格
[root@hero ~]# awk '/oldboy/{print $2,$5}' /oldboy/oldboy.txt
oldboy 15000;15000;2000
[root@hero ~]# awk '/oldboy/{print $2" "$5}' /oldboy/oldboy.txt
oldboy 15000;15000;2000
指定分隔符,取出指定列信息
# 指定空格和 ; 为分隔符,取出oldboy.txt文件中含有“oldboy”那一行的第2列和第5列
[root@hero ~]# awk -F "[ ;]+" '/oldboy/{print $2,$5}' /oldboy/oldboy.txt
oldboy 15000
取出某一列匹配指定内容的信息
# 取oldboy.txt文件中第二列是“oldgirl”的行输出
[root@hero ~]# awk '$2~/oldgirl/' /oldboy/oldboy.txt
02 oldgirl 18845678923 db 20000;20000;2000
4.4 排除信息
进行文件取反操作
#单个取反
# 取oldboy.txt文件中第二列不是“oldgirl” 的行输出
[root@hero ~]# awk '$2!~/oldgirl/' /oldboy/oldboy.txt
01 oldboy 15612422861 sa 15000;15000;2000
03 oldbaby 17778953645 dev 18000;12000;3000
04 olddog 18956423145 CTO 50000;50000;5000
05 oldboy oldgirl oldbaby olddog
#多个取反
#取oldboy.txt文件中第二列不是“oldgirl”和不是“oldboy”的行输出
[root@hero ~]# awk '$2!~/oldgirl|oldboy/' /oldboy/oldboy.txt
03 oldbaby 17778953645 dev 18000;12000;3000
04 olddog 18956423145 CTO 50000;50000;5000
4.5 替换信息
替换操作参数:
gsub(/要替换的信息/,"替换成什么信息",将第几列进行替换)
# 将文件oldboy.txt中的第2列是“olddog”行的 ; 替换成 ¥
[root@hero ~]# awk '$2~/olddog/{gsub(/;/,"¥",$5);print $2,$5}' /oldboy/oldboy.txt
olddog 50000¥50000¥5000
4.6 高级使用方法
4.5.1 特殊模式(BEGIN、END)
语法:awk '[BEGIN]{..}{..}[END{..}]' file
BEGIN和END顾名思义,在awk中,BEGIN只在开始处理之前运行一次,END只在结束处理之后运行一次,非常适合用在做一些前置操作时使用,通常求和类初始化值、设定分隔符等经常会用。
BEGIN
1. 在处理文件之前做什么操作动作
# 在oldboy.txt文件内容的第一行添加“人员工资收入表”
[root@hero ~]# awk 'BEGIN{print "人员工资收入表"}{print $0}' /oldboy/oldboy.txt
人员工资收入表
01 oldboy 15612422861 sa 15000;15000;2000
02 oldgirl 18845678923 db 20000;20000;2000
03 oldbaby 17778953645 dev 18000;12000;3000
04 olddog 18956423145 CTO 50000;50000;5000
05 oldboy oldgirl oldbaby olddog
06 oldgirl oldboy oldbaby olddog
2. 可以实现计算器功能
[root@hero ~]# awk 'BEGIN{print 30-2}'
28
END
1. 在处理完文件之后做什么操作
# 在oldboy.txt文件内容的最后一行添加“人员工资收入表”
[root@hero ~]# awk 'END{print "人员工资收入表"}{print $0}' /oldboy/oldboy.txt
01 oldboy 15612422861 sa 15000;15000;2000
02 oldgirl 18845678923 db 20000;20000;2000
03 oldbaby 17778953645 dev 18000;12000;3000
04 olddog 18956423145 CTO 50000;50000;5000
05 oldboy oldgirl oldbaby olddog
06 oldgirl oldboy oldbaby olddog
人员工资收入表
4.5.2 内置变量
awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出最常用的一些变量
变量名称 变量解释 ARGC 命令行参数个数 ARGV 命令行参数排列 ENVIRON 支持队列中系统环境变量的使用 FILENAME awk浏览的文件名 FNR 浏览文件的记录数 FS 字段分隔符变量,等价于命令行 -F 选项 NF 表示最后一列 NR 表示行号信息 OFS 输出域分隔符 ORS 输出记录分隔符 RS 控制记录分隔符
NF
# 输出文件最后一列信息
[root@hero ~]# awk '{print $NF}' /oldboy/oldboy.txt
15000;15000;2000
20000;20000;2000
18000;12000;3000
50000;50000;5000
# 输出文件倒数第二行信息
[root@hero ~]# awk '{print $(NF-1)}' /oldboy/oldboy.txt
sa
db
dev
CTO
NR
# 输出文件第二行信息
[root@hero ~]# awk "NR==2" /oldboy/oldboy.txt
02 oldgirl 18845678923 db 20000;20000;2000
FS
修改字段分隔符:
-F":" == BEGIN{FS=":"} == -vFS=":"
# 修改oldboy.txt文件中分隔符为 ; 并输出含有“oldboy”行信息的第2列和第3列
1. 方法一:
[root@hero ~]# awk -F";"+ '/oldboy/{print $2,$3}' /oldboy/oldboy.txt
15000 2000
2. 方法二:
[root@hero ~]# awk 'BEGIN{FS=";"}/oldboy/{print $2,$3}' /oldboy/oldboy.txt
15000 2000
3. 方法三:
[root@hero ~]# awk -vFS=";" '/oldboy/{print $2,$3}' /oldboy/oldboy.txt
15000 2000
4.5.3 统计算法
累加算法
累加算法公式:i=i+1
# 使用累加算法,求在oldboy.txt文件中,有几行第二列含有“oldboy”
[root@hero ~]# awk '$2~/oldboy/{i=i+1}END{print i}' /oldboy/oldboy.txt
2
求和算法
求和算法公式:i=i+$x
# 使用求和算法,计算oldboy.txt文件中含有“oldboy”行的第五列累加结果是多少(由上一题可知,文件中共有两行第二列为oldboy)
1. 显示计算过程
[root@hero ~]# awk -F "[ ;]"+ '$2~/oldboy/{i=i+$5;print i}' /oldboy/oldboy.txt
15000
30000
2. 不显示计算过程
[root@hero ~]# awk -F "[ ;]"+ '$2~/oldboy/{i=i+$5}END{print i}' /oldboy/oldboy.txt
30000
# 求差
1. 显示计算过程
[root@hero ~]# awk -F "[ ;]"+ -vi=50000 '$2~/oldboy/{i=i-$5;print i}' /oldboy/oldboy.txt
35000
20000
2. 不显示计算过程
[root@hero ~]# awk -F "[ ;]"+ -vi=50000 '$2~/oldboy/{i=i-$5}END{print i}' /oldboy/oldboy.txt
20000