AWK入门到精通系列——awk快速入门
Posted 连智波
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AWK入门到精通系列——awk快速入门相关的知识,希望对你有一定的参考价值。
简介
AWK是一个优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言(其名称得自于它的创始人阿尔佛雷德·艾侯、彼得·温伯格和布莱恩·柯林汉姓氏的首个字母)的最大功能取决于一个人所拥有的知识。awk经过改进生成的新的版本nawk,gawk,现在默认linux系统下日常使用的是gawk,用命令可以查看正在应用的awk的来源(ls -l /bin/awk )
一个简单的例子
#创建一个文件
vim awk.txt
Beth 4.00 0
Dan 3.75 0
Kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
字段解释: 姓名 每小时工资 工作时长
#打印每位员工的名字以及报酬
awk $3>0 print $1,$2*$3 awk.txt
$3>0 是模式
print $1,$2*$3是动作
#想知道哪些员工在偷懒
awk $3==0 print $1 awk.txt
执行结果图:
AWK程序结构
- AWK程序执行流程
awk的基本操作是在由输入行组成的序列中, 陆续地扫描每一行, 搜索可以被"模式"匹配(match) 的行.如果匹配则执行"动作",一直持续到所有的输入被读取完毕
- 模式-动作分析
(1)模式-动作都存在 awk $3==0 print $1 awk.txt
(2)模式存在,动作不存在 awk $3==0 awk.txt
(3)模式不存在,动作存在 awk print $1 awk.txt
(4)不可以两者都不存在(不能够运行)
AWK命令的运行格式
#后面接文件
awk $3==0 print $1 awk.txt 后面接一个文件
awk $3==0 print $1 awk.txt awk02.txt 后面接两个文件
#等待输入
awk $3==0 print $1 后面不接任何文件,等待输入再去判断
#将awk程序放入文件中
cat program
$3==0 print $1
执行命令: awk -f program awk.txt
AWK的输出格式
- 数据类型
数字和字符串
- 行和字段
awk从它的输入中每次读取一行,将行分解为一个个的字段(默认将字段看作是非空白字符组成的序列).
当前输入行的第一个字段叫作$1,第二个是$2,依次类推,一整行记为$0,每行的字段数有可能不一样.
- 案例
#打印每一行
awk print awk.txt 或 awk print $0 awk.txt
#打印某些字段
awk print $1,$3 awk.txt
#打印每行的字段数量(内建变量NF)
awk print NF awk.txt
#打印第一个字段和最后一个字段
awk print $1,$NF awk.txt
#计算和打印
awk print $1,$2 * $3 awk.txt
#打印行号(NR)
awk print NR,$0 awk.txt
#拼接字符串和字段
awk print $1,"今天的收入是",$2 * $3 awk.txt
#格式化输出
awk printf("%s 今天的收入是 $%.2f\\n",$1,$2*$3) awk.txt
固定宽度输出
awk printf("%-8s 今天的收入是 $%6.2f\\n",$1,$2*$3) awk.txt
输出排序
awk printf("%6.2f,%-8s 今天的收入是 $%6.2f\\n",$2*$3,$1,$2*$3) awk.txt |sort -nk3 -t,
AWK模式匹配
- 单模式
#每小时工资大于5的记录
awk $2>5 print $0 awk.txt
#报酬超过50的员工
awk $2*$3>50 print $1,$2*$3 awk.txt
#查询名字为Mark的记录
awk $1=="Mark" print $0 awk.txt
#正则表达式匹配名字带有Mar的记录
awk /Mar/ print $0 awk.txt
- 模式组合
#打印那些$2至少为4,或者$3至少为20的行
awk $2>=4||$3>=20 print $0 awk.txt
awk !($2<4&&$3<20) print $0 awk.txt
#打印那些$2至少为4,并且$3至少为20的行
awk $2>=4 && $3>=20 print $0 awk.txt
- BEGIN 与 END
特殊的模式 BEGIN 在第一个输入文件的第一行之前被匹配, END 在最后一个输入文件的最后一行被处理之后匹配.
awk BEGIN ********* END***********
awk BEGIN print "NAME RATE HOURS" print ENDprint "END" awk.txt
awk BEGIN print "NAME RATE HOURS";print "------" print ENDprint "------";print "END" awk.txt
用AWK计算
- 计算总和
#工作时长超过15小时的员工总人数
awk $3>15 emp=emp+1 ENDprint emp,"工作时长超过15小时的员工人数" awk.txt
- 计算平均数
#计算员工的平均工资
awk pay=pay+$2*$3 ENDprint NR,"员工总人数";print "总工资",pay; print "平均工资",pay/NR awk.txt
- 查找最大值
#查找每小时工资最高的员工
awk $2 >maxrate maxrate=$2;maxemp=$1 ENDprint "每小时工资最高的员工是:",maxemp,"工资是:",maxrate awk.txt
- 打印最后一行
awk last=$0 ENDprint last awk.txt
字符串拼接
#name之间加一个空格
awk names=names $1 " " ENDprint names awk.txt
内建函数
#length 求字符串长度
计算名字的长度
awk print $1,length($1) awk.txt
#计算文本的行数,总字段数,总字节数
awk nc=nc+length($0)+1;nw=nw+NF ENDprint NR,"lines,",nw,"words,",nc,"characters" awk.txt
流程控制语句
- if-else语句
#查找每小时工资多于 $6.00 的雇员的总报酬与平均报酬
awk $2>6 n=n+1;pay=pay+$2*$3 ENDif(n>0) print n,"employees,total pay is",pay,"average pay is",pay/n;else print "not exit" awk.txt
- while语句
计算1到100总和
awk BEGIN test=100; total=0; while(i<=test) total+=i; i++; print total; 5050
#shell脚本
#!/bin/bash
total=0
i=0
while [ $i -le 100 ]
do
let total+=$i
let i++
done
echo $total
- for语句
#计算1到100的总和
awk BEGIN total=0; for(i=0;i<=100;i++) total+=i; print total;
- 数组
#倒着打印每行记录
awk line[NR] = $0 END i=NR; while (i>0) print line[i];i=i-1 awk.txt
awk line[NR] = $0 ENDfor(i=NR;i>0;i--)print line[i] awk.txt
AWK 生产案例
#输入的总行数
awk ENDprint NR awk.txt
#打印第2行
awk NR==2 print $0 awk.txt
#打印每行最后一个字段
awk print $NF awk.txt
#打印最后一行最后一个字段
awk field=$NF ENDprint field awk.txt
#打印字段数多于 2 个的输入行
awk NF>2 print $0 awk.txt
#打印最后一个字段值大于 4 的输入行
awk $NF>4print $0 awk.txt
以上是关于AWK入门到精通系列——awk快速入门的主要内容,如果未能解决你的问题,请参考以下文章