22. 处理命令行参数
awk 可以从内置数组 ARGV 中得到命令行参数,其中包括命令 awk 。但所有传递给 awk 的选项不再其中。 ARGV 数组下标从 0 开始。 ARGC 是一个包含命令行参数个数的内置变量。
23.awk 的内置函数
字符串函数
sub 函数匹配记录中最大、最靠左边的子字符串的正则表达式,并用替换字符串替换这些字符串。如果没有指定目标字符串就默认使用整个记录。替换只发生在第一次匹配的时候。
格式: sub (regular expression, substitution string):
sub (regular expression, substitution string, target string)
例 20 :
$ awk '{ sub(/test/, "mytest"); print }' testfile
$ awk '{ sub(/test/, "mytest"); $1}; print }' testfile
第一个例子在整个记录中匹配,替换只发生在第一次匹配发生的时候
第二个例子在整个记录的第一个域中进行匹配,替换只发生在第一次匹配发生的时候。
gsub 函数作用如 sub ,但它在整个文档中进行匹配。
格式: gsub (regular expression, substitution string)
gsub (regular expression, substitution string, target string)
index 函数返回子字符串第一次被匹配的位置,偏移量从位置 1 开始。
格式: index(string, substring)
length 函数返回记录的字符数,若未指定参数,则 length 函数返回记录中的字符个数
格式: length( string )
length
substr 函数返回从字符串指定位置开始的子字符串,如果指定长度超过实际长度,就返回其实际内容。
格式: substr( string, starting position )
substr( string, starting position, 子串长度 )
match 函数返回在字符串中正则表达式位置的索引,如果找不到指定的正则表达式则返回 0 。 match 函数把内置变量 RSTART 设为子串在字符串中的起始位置, RLENGTH 为则设为子串的长度。这些变量可以被 substr 函数用来提取相应模式的子串。
格式: match( string, regular expression )
例 21 :
$ awk '{start=match("this is a test",/[a-z]+$/); print start}' filename
$ awk '{start=match("this is a test",/[a-z]+$/); print start, RSTART, RLENGTH }'/ filename
第一个实例打印以连续小写字符结尾的开始位置,这里是 11 。
第二个实例还打印 RSTART 和 RLENGTH 变量,这里是 11(start) , 11(RSTART) , 4(RLENGTH) 。
toupper 和 tolower 函数可用于字符串大小间的转换,该功能只在 gawk 中有效。
格式: toupper( string )
tolower( string )
split 函数可按给定的分隔符把字符串分割为一个数组。如果分隔符没提供,则按当前 FS 值进行分割。
格式: split( string, array, field separator )
split( string, array )
例 22 :
$ awk '{ split( "20:18:00", time, ":" ); print time[2] }' filename
把时间按冒号分割到 time 数组内,并显示第二个数组元素 18 。
sprintf 函数 返回一个指定格式的表达式。可以在 sprintf 函数中使用 printf 函数的格式规范
格式: variable=sprintf(“ 含有格式说明的字符串” , 表达式 1, 表达式 2 , .., 表达式 n)
内置算术函数
int(x)
returns nearest integer to x, located between x and zero and truncated toward zero.
sqrt(x)
returns the positive square root of x. gawk reports an error if x is negative.
exp(x)
returns the exponential of x (e ^ x) or reports an error if x is out of range.
log(x)
returns the natural logarithm of x, if x is positive; otherwise, it reports an error.
sin(x)
returns the sine of x, with x in radians.
cos(x)
returns the cosine of x, with x in radians.
atan2(y, x)
returns the arctangent of y / x in radians.
rand()
returns a random number , uniformly distributed between zero and one ( 0<=value<1 )
srand
(
x)
function srand
sets the seed, for generating random numbers to the value x
时间函数
systime 函数返回从 1970 年 1 月 1 日开始到当前时间 ( 不计闰年 ) 的整秒数。
格式: systime()
strftime 函数使用 C 库中的 strftime 函数格式化时间。
日期和时间格式说明符
格式 描述
%a 星期几的缩写 (Sun)
%A 星期几的完整写法 (Sunday)
%b 月名的缩写 (Oct)
%B 月名的完整写法 (October)
%c 本地日期和时间
%d 十进制日期
%D 日期 08/20/99
%e 日期,如果只有一位会补上一个空格
%H 用十进制表示 24 小时格式的小时
%I 用十进制表示 12 小时格式的小时
%j 从 1 月 1 日起一年中的第几天
%m 十进制表示的月份
%M 十进制表示的分钟
%p 12 小时表示法 (AM/PM)
%S 十进制表示的秒
%U 十进制表示的一年中的第几个星期 ( 星期天作为一个星期的开始 )
%w 十进制表示的星期几 ( 星期天是 0)
%W 十进制表示的一年中的第几个星期 ( 星期一作为一个星期的开始 )
%x 重新设置本地日期 (08/20/99)
%X 重新设置本地时间 (12 : 00 : 00)
%y 两位数字表示的年 (99)
%Y 当前月份
%Z 时区 (PDT)
%% 百分号 (%)
格式: strftime( [format specification][,timestamp] )
24. 用户自定义函数
脚本中凡是可以出现模式操作规则的位置都可以放置用户自定义的函数。
格式: 函数名 ( 参数 , 参数 , 参数 , ...){
语句
return 表达式
( 注: return 语句和表达式都是可选项 )
}
变量以参数值的方式传递,且仅在使用它的函数中局部有效。函数使用的只是变量的副本。数组则通过地址或引用被传 递,因此,可以在函数中直接修改数组的元素。函数中的变量只要不是从参数列表传来的,都视为全局变量。调用函数时,如果没有指定某个形参的值,该参数被初 始化为空。
例 23 :
long@long-Ubuntu:~$ cat grades
44 55 66 22 77 99
100 22 77 99 33 66
55 66 100 99 88 45
long@long-Ubuntu:~$ cat sorter.sc
#Scriptname: sorter
#It sorts numbers in ascending order
function sort(scores, num_elements, temp, i, j){
#temp,i,j will be local and private
#with an initial value of null
for(i=2; i<=num_elements; ++i){
for(j=i; scores[j-1]>scores[j]; --j){
temp = scores[j]
scores[j] = scores[j-1]
scores[j-1] = temp
}
}
}
{for (i=1; i<=NF; i++)
grades[i] = $i
sort(grades,NF)
for(j=1;j<NF;++j)
printf("%d ", grades[j])
printf("/n")
}
long@long-Ubuntu:~$ awk -f sorter.sc grades
22 44 55 66 77
22 33 66 77 99
45 55 66 88 99
25. 杂项
固定字段
有些数据没有明显的字段分隔符,却有固定宽度的列。预处理这些数据时, substr 很有用
空字段
用固定长度的字段来存储数据,就可能出现一些空字段, substr 可以被用来保存字段,而不考虑它们是否包含数据
26.awk 命令选项
-F fs or --field-separator fs
指定输入文件折分隔符, fs 是一个字符串或者是一个正则表达式,如 -F: 。
-v var=value or --asign var=value
赋值一个用户定义变量。
-f scripfile or --file scriptfile
从脚本文件中读取 awk 命令。
-mf nnn and -mr nnn
对 nnn 值设置内在限制, -mf 选项限制分配给 nnn 的最大块数目; -mr 选项限制记录的最大数目。这两个功能是 Bell 实验室版 awk 的扩展功能,在标准 awk 中不适用。
-W compact or --compat, -W traditional or --traditional
在兼容模式下运行 awk 。所以 gawk 的行为和标准的 awk 完全一样,所有的 awk 扩展都被忽略。
-W copyleft or --copyleft, -W copyright or --copyright
打印简短的版权信息。
-W help or --help, -W usage or --usage
打印全部 awk 选项和每个选项的简短说明。
-W lint or --lint
打印不能向传统 unix 平台移植的结构的警告。
-W lint-old or --lint-old
打印关于不能向传统 unix 平台移植的结构的警告。
-W posix
打开兼容模式。但有以下限制,不识别: /x 、函数关键字、 func 、换码序列以及当 fs 是一个空格时,将新行作为一个域分隔符;操作符 ** 和 **= 不能代替 ^ 和 ^= ; fflush 无效。
-W re-interval or --re-inerval
允许间隔正则表达式的使用,参考 (grep 中的 Posix 字符类 ) ,如括号表达式 [[:alpha:]] 。
-W source program-text or --source program-text
使用 program-text 作为源代码,可与 -f 命令混用。
-W version or --version
打印 bug 报告信息的版本。