在开始学习awk的时候, 我们就学到了, 构成awk脚本语句的基本框架. 即 Pattern { Action }, 我们把一对Pattern { Action } 成为一个规则(Rule). 今天,我们进一步来学习如何建立pattern和action,以及内建变量(Variable)的使用.
1. Pattern
awk是否执行一条规则,取决于输入记录是否跟Pattern匹配. 常见的Pattern有:
/ regexp / 正则表达式, 当输入记录符合正则表达式时, 即认为输入记录是匹配的.
expression 表达式, 当 不为0( 作为数据) 或者 不为空(作为字符串)时, 匹配
Pat1, Pat2 这是一对Pattern, 它匹配一个范围, 包括匹配Pat1的输入记录, 一直到匹配Pat2的记录
BEGIN, END 这是两个特殊的Pattern, 之前我们也用到过很多次了. BEGIN和END给我们提供了做初始化和清除工作的机会.
empty 即Pattern为空, 这个时候, 匹配所有的输入记录.
2. 在awk中使用shell变量
在Pattern一节中,我之简单的总结了一下Pattern的类型, 而没有做进一步的介绍. 这是因为前面的学习中, 这些类型我们都已经接触过了. 这一节中, 我们来学习如何在awk程序中使用shell的变量.
我们知道shell变量的引用是通过在变量名前加$符号. 如$NAME, $PAT等, 在awk中,也是采用同样的方式来引用shell变量的值. 但是需要使用双引号括起来,才能完成变量替换.
另外我们还可以在awk命令行中, 将shell变量赋值给awk变量,这样在awk程序中, 就不用关心shell变量了,这是推荐使用的方式.
两种使用方式的例子如下:
方式一:
echo -n "Enter search pattern: " read pattern awk "/$pattern/ "’{ nmatches++ } END { print nmatches, "found" }’ /path/to/data
方式二:
echo -n "Enter search pattern: " read pattern awk -v pat="$pattern" ’$0 ~ pat { nmatches++ } END { print nmatches, "found" }’ /path/to/data
3. action
action包含在{ }中,由一条或者多头awk语句组成。每条语句由换行或者分号隔开。Action中的语句包含以下几种类型:
表达式 ---- 调用函数, 或者给变量赋值都属于此类语句.
控制语句 --- awk的控制语句由if, for, while, do组成. 其语法跟C语言类似.
复合语句 --- 用{ } 括起来的一条或多条语句. 一般用在将多条语句组合在一起,作为if, for, while, do 的执行体.
输入语句 --- getline, next, nextfile
输出语句 --- print 和 printf
删除语句 --- delete, 删除数组元素
这些语句在之前的学习中, 我们基本上都碰到过了,这里就不在详细说了.
4. 控制语句
在任何编程语言,控制语句的作用都至关重要, 因为它控制了程序的走向. 本节将对awk提供的几种控制语句做详细的介绍
a) 先来看 if .
if控制语句语法为
if ( condition ) then-body [else else-body]
当 condiation的值为TRUE时, 执行then-body, 反之,则执行else-body. 当Condition的值为0或者null-string时, condition判断为FALSE.
看个例子:
if ( x % 2 == 0 )
print "x is even"
else
print "x is odd"
b) while
while语法为
while (condition )
body
c) do-while
do
body
while (condition)
d) for
for (initialization; condition; increment)
body
e) switch-case
switch (expression) {
case value or regular expression:
case-body
default:
default-body
}
f) break
g) continue
h)next
next 语句强迫awk立即结束当前记录的处理, 读取下一记录,重新开始.
i)nextfile
nextfile语句立即结束当前文件中记录的处理,读取下一个文件的记录(如果有的话)
j)exit
exit [return code]
结束整个awk脚本.
5. 内建变量
awk脚本允许使用变量,大部分变量都是用户自己定义,自己使用. 但也存在一些内建变量,允许用户给其赋予新值,从而告诉awk做特定的事情.另外还有一些内建变量保存有awk的内部信息,供用户访问.
变量 | 说明 |
---|---|
BINMODE# | BINMODE=0 or "r" 读取采用二进制, 1 or "w" 写入采用二进制, 3 or "rw" 读取,写入采用二进制 |
CONVFMT | 数值转化为字符串的格式,缺省为 %.6g |
FIELDWIDTHS # | 指定字段固定宽度,将记录分割成字段 |
FS | 指定字段分隔符 |
IGNORECASE # | 不为零或者不为空, 则大小写无关, 但是数组的下标和单字符字段分隔符例外. |
LINT # | |
OFMT | |
OFS | |
ORS | |
RS | |
SUBSEP | 多维数组索引组合/分割的间隔符 |
TEXTDOMAIN # | |
ARGC, ARGV | 参数个数, 和参数数组, 注意 -v 和 脚本本身是不计算在参数内的. |
ARGIND # | 当前正在处理的参数索引 |
ENVIRON | 环境变量数组,通过环境变量名检索 |
ERRNO # | getline/close 访问文件时,出错号 |
FILENAME | 当前正在读取的文件的名字 |
FNR | 当前文件的记录数 |
NF | 当前记录的字段数 |
NR | 记录数 |
PROCINFO # | 为一数组,其元素为当前awk进程的信息 |
RLENGTH | match函数,匹配字符串的长度, 如未匹配,值为-1 |
RSTART | match函数运行后设置, 其值为匹配字符串的起始位置. |
RT # | 每读入一条记录时,重新设置. 其值为匹配RS的字符串的值 |