(一) 什么是awk
awk其实相当于一门可以处理数据文本的语言,这么说的原因是其具有很多类c语言的语法,如:变量,数组,函数,流程控制等,其由Aho,Weinberger,Kernighan大约在1977年开发完成,随后被引入unix/linux中。
(二) awk可以干什么
awk是一个非常强大的数据处理工具,可对文本进行的编辑,筛选,其非常适用于处理有行和列组成的文本数据,就像处理数据库中的记录一样,可以删除列,添加列或者删除行,修改行与添加行等一系列操作,非常实用。
(三)awk的基本语法
一般形式:awk pattern {actions} filename
- 【pattern】:表示匹配模式。
- 【{action}】:要执行的操作
说明:以上语法表示当某个问本行负符合pattern指定的匹配规则时,执行action操作。
注意:以上pattern与{actions}是可选的,但是必须有其中一个,并且action前面的左大括号需要与pattern位于同一行中,尼玛,我就吃过这一次亏,特此强调。
(四) 执行awk程序的几种方式
(1)通过命令执行awk程序
例如:
awk ‘{print}’ filename 输出filenam全部的数据
awk ‘/^T/ {print} ’ filename 输出行首为T的文本行
(2)通过awk脚本
例如:
把awk ‘/^T/ {print} ’ filename 中的’/^T/ {print} ‘写入test文本文件中,然后执行**awk -f test filename 就达到和上述一样的效果了。
(3)通过可执行程序
例如:
直接将 awk ‘/^T/ {print} ’ filename写入脚本文件test.awk中如下:
#! /usr/bin/awk -f
'/^T/ {print} '
赋予该脚本可执行权限后,执行:./test.awk filename 就OK.
(五) awk的模式匹配,即pattern中可以使用的形式
(1)关系表达式,既可以使用> ,< ,== ,!=等关系表达式作为匹配模式,进行筛选。
例如:
awk ‘$2>80 {print}’ filename 显示第二列大于80的行。
(2)正则表达式,既可以使用[$,.,^,* ,[]]等正则表达式作为匹配模式,进行筛选。
例如:
#! /usr/bin/bash
result=`awk '/^T/ {print}' filename `
result=`awk '/^(Tom|Key)/ {print}' filename `
echo $result
(3)混合模式,即既可以使用关系表达式又可以使用正则表达式进行混合。
例如:
#! /bin/bash
result=`awk '/^T/ && $2 > 80 {print}' filename `
echo $result
(4)区间模式,通过条件匹配一段连续的问本行。
例如:
#! /bin/bash
#匹配/^Tom/与$2=90行之间的行
result=`awk '/^Tom/,$2=90 {print}' filename `
echo $result
(5)BEGIN模式
该模式是一种特殊的你内置模式,执行于awk程序还没有读取文本行之前,该模式仅仅被执行一次,当awk读取数据以后BEGIN不再成立。
例如:
#! /usr/bin/awk -f
#输出字符串
BEGIN{ print "hello world!"}
又如:
#! /usr/bin/awk -f
#可以在开始执行awk前定义变量并进行一系列的初始化工作
BEGIN{
FS="[\t:]"
RS="\n"
count=30
print RS count
}
(6)END模式
该模式是一种特殊的你内置模式,执行于awk程序读取文本行并处理完以后,即将推出程序是执行,相当于做善后操作,该模式所对应的操作只执行一次。
例如:
#! /usr/bin/awk -f
#程序退出时显示提示信息
END{
print "code end"
}
(六) awk提供的系统函数
- index(str1,str2):返回str2在str1中的位置,如果有多个匹配,则返回第一个位置,否则返回0。
- length(str) :字符串长度
- split(str,arr,seperator):以seperator为分隔符把str分割存入数组arr中
- match(str,regexp):在str中搜索符合正则表达式regex的子字符串。
- sub(regexp,replace,str):将str中第一个符合正则表达式regexp的子字符串替换为replace。
- gsub(regexp,replace,str):将str中全部符合正则表达式regexp的子字符串替换为replace。
- substr(str,start,length):将字符串str中截取指定的子字符串。
- 算术函数 想了解的自己查吧,这个太啰嗦。
(七) awk的流程控制
(1)判断
if(exp)
{
statement
...
}
else
{
statement
...
}
(2)循环
for(i=0; i<n;i++)
{
statement
...
}
或
while( exp )
{
statement
...
}
或
do
{
statement
...
}while( exp );
(3)控制
- break
- continue
- next 和cotinue不同,next并不用在循环结构中,而是用在整个awk中,当awk执行程序时,如果遇到next语句,则该语句中所有的程序语句都被忽略,awk则会读取下一行数据,并且从第一个模式及操作开始执行。
例如:
#! /usr/bin/awk -f
##当读取的行为空行时,跳过后面的语句
/^[\t]*$/{
next
}
{
print $1,$2,$3,$4
}
- exit
(八) awk的格式化输出
(1)print
(2)priint(“format”,num);
(3)sprintf(“format”,num):sprintf()函数的功能与prntf()函数大致相同,但是该函数只是以字符串的形式返回格式化结果,并不输出到标准设备。可以使用该函数的返回结果使用print,printf()输出到标准设备上。
#! /usr/bin/awk -f
BEGIN{
print "begin"
total=0
}
{
printf("%s\t%d\t%d\t%d\t\n",$1,$2,$3,$4)
total=total+$2+$3+$4
}
END{
##计算平均分
ave=total/NR
##输出统计结果
sum=sprintf("Total:%d stutents,ave:%0.2f",NR,ave);
print sum
}
(九) awk与shell的交互使用
(1)通过管道实现与shell的交换
例如:
#! /usr/bin/awk -f
BEGIN{
#通过管道来执行who命令的执行结果
while("who" | getline )
{
i++
}
printf("there are %d online users",n)
}
上述例子中,通过管道来执行who命令,将执行结果传递给getline函数,该函数依次读取每一行数据
(2)通过system函数实现与shell的交互
例如:
#! /usr/bin/awk -f
BEGIN{
system("ls > filename")
while( getline < "filename" > 0 )
{
print $1
}
}
上述例子中,使用system函数执行ls命令,由于system 不支持函数的传递,所以必须将结果重定向到filename文件中,然后用getline函数重新读取出来。