1、工作方式:
在命令行中使用,但更多是作为脚本来使用。awk将输入数据分成若干个记录(Record),每个记录又分成若干个域(Field),以记录为基本单位进行操作。在默认状态下,换行符“/n”是记录分割符(RS),空格或制表符是域分隔符(FS)。$0代表当前记录,$1,$2...代表第1,2...个域。
2、基本语法:
(1)命令行直接调用:
awk [options] '/pattern/{action}' filename
(2)脚本文件调用:
awk [options] -f scriptfile filename
3、模式与操作:
每一个awk语句都可以归结为以下形式:pattern {action},其含义是每当被处理的数据中发现与pattern相匹配的模式时,就执行action对应的动作。其中pattern可以通过逗号分开不同的匹配模式,即pattern1和pattern2之间出现的每一个记录(包含pattern1和pattern2所在的记录)都执行规定的action操作,action中多个操作由换行符或分号分开。当pattern为空时,可匹配任何模式;当action为空时,则默认执行{print $0},即显示当前记录。
4、脚本文件编写:
(1)开始处应有#!/bin/awk -f,否则可能造成错误
(2)BEGIN和END是两个特殊的模式,其功能分别是控制初始化工作和对数据进行包装。BEGIN在第一个记录读入前就匹配,也就是说,在awk还未读入任何记录前就要将BEGIN部分的动作执行一遍。而END则在输入的末尾匹配,换言之,在读入所有记录后执行END部分的动作。
(3)以#开头的语句是注释语句;一个语句一般占一行;用分号(;)分隔的多个语句也可以占一行;行末的反斜线(/)表示续行;而且,以逗号(,)结束的语句将继续进行,也就是说:行末的逗号也表示续行。
(4)通过花括号将多个简单语句括起来,可以形成复合语句
5、变量:
(1)内部变量:
ARGC 命令行中的参数个数
ARGV 命令行参数构成的数组
FILENAME 当前输入文件的名字
FS 域分隔符,默认为空格或制表符
OFS 输出结果中的域间分隔符,默认为空格
NF 当前记录所包含的域数
RS 记录分隔符,默认为换行符
ORS 输出结果中的记录分隔符,墨认为换行符
NR 当前已读的记录数
FNR 当前文件中的当前记录号
注意FNR与NR的区别:awk每处理完一个输入文件后,FNR将在开始处理下一个输入文件时被清零,而NR却不被清零。
(2)用户自定义变量:
用户变量在awk语言中不需要定义
6、函数:
(1)内置函数:
为了表述方便,在描述串函数的功能时,我们用l和p表示整数,R表示正则表达式,s和t表示串,下面是串函数的语法及功能描述:
gsub(R,s) 将当前记录中的R替换成s
gsub(R,s,t) 将t中的所有R替换成s
index(s,t) 返回s中t出现的位置,未出现返回0
match(s,R) 返回s中R出现的位置,未出现返回0
split(s,A) 用域分隔符将s分成若干段,并将其存入数组A中
split(s,A,R) 用R作为s的分隔符分成若干段,存入A
sub(R,s) 将当前记录中的第一个R替换成s
sub(R,s,t) 将t中的第一个R替换成s
systime() 返回从1970年1月1日开始到当前时间的整秒数
(2)自定义函数:
awk中函数的定义部分必须出现在调用该函数的所有语句之前,并且在调用自定义函数时,函数名与括起参数列表的左括号之间不能有任何字符。
7、流程控制语句:
(1)if-else
if (expression) {
statement
}else {
statement
}
(2)while
while (expression) {
statement
}
(3)for
for (expression1;expression;expression2) {
statement
}
等价于下面的语句:
expression1
while (expression) {
statement
expression2
}
或者语法格式
for (var in array) {
statement
}
(4)next和exit
除条件执行和循环语句之外,awk 还提供了next和exit两个用于控制读入数据记录的语句。next使awk废弃对当前记录的处理,并立即从输
入数据中读入下一个记录,然后从第1个pattern{action}语句开始执行。而exit语句不但废弃对当前记录的处理,而且也不再继续读入新的记录,如果awk程序中有END动作,则执行该动作,然后退出;如果awk程序中无END动作,则立即退出。
exit语句的句法格式为:
exit [expression]
8、典型实例
(1)awk '/^awk/,/^mysql/' test 打印以root开头的记录到以mysql开头的记录范围内所有记录,如果没有以mysql开头的记录则打印到文尾
(2)awk '$1~/[0-9][0-9]$/{print$1}' test如果第一个域以两个数字结束就打印这个记录
(3)awk '/^(no|so)/' test打印所有以模式no或so开头的行
(4)awk '{print ($1 > 5 ? "ok "$1: "error"$1)}' test如果第一个域大于5则打印问号后面的表达式值,否则打印冒号后面的表达式值。
(5)awk 'BEGIN{printf "What is your name?"; getline name < "/dev/tty" } $1 ~name {print "Found" name on line ", NR "."} END{print "See you," name "."} test。在屏幕上打印”What is your name?",并等待用户应答。当一行输入完毕后,getline函数从终端接收该行输入,并把它储存在自定义变量name中。如果第一个域匹配变量 name的值,print函数就被执行,END块打印See you和name的值
Referrence:
http://www.linux.gov.cn/shell/awk.htm Awk学习笔记
http://fanqiang.chinaunix.net/program/other/2005-09-07/3621.shtml awk使用手册
模式扫描与处理——awk 语言