(d)为什么执行close("data.rpt") ? 因为sort完后的资料也将写到data.rpt,而该文件正为awk所打开使用(write)中,故awk程式中应先关闭data.rpt.以免造成因二个processes同时打开一个文件进行输出(write)所产生的错误.
l system指令
该指令用以执行Shell上的command.
范例:
DataFile = "invent.rpt"
system( "rm " DataFile )
说明:
(a)system("字符串")指令接受一个字符串当成Shell的命令.上例中,使用一个字串常数"rm "连接(concate)一个变量DataFile形成要求Shell执行的命令.Shell实际执行的命令为"rm
invent.rpt".
l "|" pipe指令
"|"配合awk输出指令,可把output到stdout的资料继续转送给Shell上的某一命令当成input的资料.
"|" 配合awk getline指令,可呼叫Shell执行某一命令,再以awk的getline指令将该命令的所产生的资料读进awk程序中.
范例:
{ print $1, $2 * $3 | "sort -k 1 >
result" }
"date" | getline Date_data
读者请参考7.2节,其中有完整的范例说明.
Øawk释放所占用的记忆体的指令
awk程式中常使用数组(Array)来记忆大量数据, delete指令便是用来释放数组中的元素所占用的内存空间.
范例:
for( any in X_arr )
delete X_arr[any]
读者请留心,
delete指令一次只能释放数组中的一个元素.
Øawk中的数学运算符(Arithmetic Operators)
+(加), -(減),
*(乘), /(除), %(求余数), ^(指数)与C语言中用法相同
Øawk中的赋值运算符(Assignment Operators)
=, +=, -=, *= , /=, %=, ^=
x += 5的意思为x = x + 5,其余类推.
Øawk中的条件运算符(Conditional Operator)
语法:
判断条件? value1 : value2
若判断条件成立(true)则返回value1,否则返回value2.
Øawk中的逻辑运算符(Logical Operators)
&&( and ), ||(or), !(not)
Extended Regular Expression中使用"|"表示or请勿混淆.
Øawk中的关系运算符(Relational Operators)
>, >=, <, < =, ==, !=, ~, !~
Øawk中其它的运算符
+(正号), -(负号),
++(Increment Operator), - -(Decrement Operator)
Øawk中各运算符的运算级
按优先高低排列:
$ (栏位运算元,例如:
i=3; $i表示第3栏)
^
(指数运算)
+ ,- ,! (正,负号,及逻辑上的not)
* ,/ ,% (乘,除,余数)
+ ,-
(加,減)
>, >
=,< , < =, ==, != (关系运算符)
~, !~
(match, not match)
&& (逻辑上的and)
|| (逻辑上的or )
?
: (条件运算符)
= , +=, -=,*=, /=, %=,
^= (赋值运算符)
14. 附录C
── awk的內建函数(Built-in Functions)
Ø(一).字串函数
l index(原字串,找寻的子字串):
若原字串中含有欲找寻的子字串,则返回该子字串在原字串中第一次出现的位置,若未曾出现该子字串则返回0.
例如执行:
$ awk 'BEGIN{ print index("8-12-94","-") }'
结果印出
2
l length(字串) :返回该字串的长度.
例如执行:
$ awk 'BEGIN { print length("John")
'}
结果印出
4
l match(原字串,用以找寻比对的正则表达式):
awk会在原字串中找寻合乎正则表达式的子字串.若合乎条件的子字串有多个,则以原字串中最左方的子字串为准.
awk找到该字串后会依此字串为依据进行下列动作:
设定awk內建变量RSTART, RLENGTH :
RSTART = 合条件的子字串在原字串中的位置.
= 0 ;若未找到合条件的子字串.
RLENGTH =合条件的子字串长度.
=
-1 ;若未找到合条件的子字串.
返回RSTART之值.
例如执行:
awk ' BEGIN {
match( "banana",
/(an)+/ )
print RSTART, RLENGTH
} '
执行结果输出
2 4
l split(原字串,数组名称,分隔字符):
awk将依所指定的分隔字符(field separator)来分隔原字串成一个个的栏位(field),并以指定的数组记录各个被分隔的栏位.
例如:
ArgLst = "5P12p89"
split( ArgLst, Arr, /[Pp]/)
执行后: Arr[1]=5,
Arr[2]=12, Arr[3]=89
l sprintf(格式字符串,项1,项2, ...)
该函数的用法与awk或C的输出函数printf()相同.所不同的是sprintf()会将要求印出的结果当成一个字串返回.一般最常使用sprintf()来改变资料格式.如: x为一数值资料,若欲将其变成一个含二位小数的资料,可执行如下指令:
x = 28
x = sprintf("%.2f",x)
执行后x
= "28.00"
l sub(比对用的正则表达式,将替換的新字串,原字串)
sub( )将原字串中第一个(最左边)合乎所指定的正则表达式的子字串改以新字串取代.
第二个参数"将替換的新字串"中可用"&"来代表"合於条件的子字串"
承上例,执行下列指令:
A = "a6b12anan212.45an6a"
sub( /(an)+[0-9]*/, "[&]", A)
print A
结果输出
ab12[anan212].45an6a
sub()不仅可执行替换(replacement)的功用,当第二个参数为空字串("")时,sub()所执行的是"去除指定字串"的功用.
通过sub()与match()的搭配使用,可逐次取出原字串中合乎指定条件的所有子字串.
例如执行下列程式:
awk '
BEGIN {
data = "p12-P34 P56-p61"
while( match( data ,/[0-9]+/) > 0) {
print substr(data, RSTART, RLENGTH )
sub(/[0-9]+/,"",data)
}
}'
结果输出:
12
34
56
61
sub( )中第三个参数(原字串)若未指定,则其预设值为$0.
可用sub( /[9-0]+/,"digital" )表示sub(/[0-9]+/,"digital",$0 )
l gsub(比对用的正则表达式,将替換的新字串,原字串)
这个函数与sub()一样,同样是进行字串取代的函数.唯一不同点是
gsub()会取代所有合条件的子字串.
gsub()会返回被取代的子字串个数.
请参考sub().
l substr(字串,起始位置[,长度] ):
返回从起始位置起,指定长度的子字串.若未指定长度,则返回起始位置到字串末尾的子字串.
执行下例
$ awk 'BEGIN { print substr("User:Wei-Lin
Liu", 6)}'
结果印出
Wei-Lin Liu
Ø(二).数学函数
l int(x) :返回x的整数部分(去掉小数).
例如:
int(7.8)将返回7
int(-7.8)将返回-7
l sqrt(x) :返回x的平方根.
例如:
sqrt(9)将返回3
若x为负数,则执行sqrt(x)时将造成Run Time Error [译者注:我这里没有发生错误,返回的是"nan"]
l exp(x) :将返回e的x次方.
例如:
exp(1)将返回2.71828
l log(x) :将返回x以e为底的对数值.
例如:
log(exp(1)) 将返回1
若x< 0 ,则执行sqrt(x)时将造成Run
Time Error. [译者注:我这里也没有发生错误,返回的是"nan"]
l sin(x) : x须以弧度为单位,sin(x)将返回x的sin函数值.
l cos(x) : x须以弧度为单位,cos(x)将返回x的cos函数值
l atan2(y,x) :返回y/x的tan反函数之值,返回值系以弧度为单位.
l rand() :返回介于0与1之间的(近似)随机数值; 0 < rand()<1.
除非使用者自行指定rand()函数起始的种子,否则每次执行awk程式时, rand()函数都将使用同一个內定的种子,来产生随机数.
l srand([x]) :指定以x为rand( )函数起始的种子.
若省略了x,则awk会以执行时的日期与时间为rand()函数起始的种子.