awk 的內建函数(Built-in Functions) (转)

 

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()函数起始的种子.

 

15.         附录D ── awk 的內建变量 Built-in Variables 

因內建变量的个数不多, 此处按其相关性分类说明, 并未按其字母顺序排列. 

 

 

 

l        ARGC

 

ARGC表示命令行上除了选项 -F, -v, -f 及其所对应的参数之外的所有参数的个数.若将"awk程式"直接写於命令列上, 则 ARGC 亦不将该"程式部分"列入计算.

 

l        ARGV 

 

ARGV数组用以记录命令列上的参数.

 

例 : 执行下列命令

 

$ awk  -F/t -v a=8 -f prg.awk  file1.dat file2.dat

 

 

$ awk  -F/t -v a=8 '{ print $1 * a }' file1.dat file2.dat

 

执行上列任一程式后

 

            ARGC    =  3

 

            ARGV[0] = "awk"

 

            ARGV[1] = "file1.dat"

 

            ARGV[2] = "file2.dat"

 

读者请留心 : 当 ARGC = 3 时, 命令列上仅指定了 2 个文件.

 

注 :

 

-F/t 表示以 tab 为栏位分隔字符 FS(field seporator).

 

-v a=8 是用以初始化程序中的变量 a.  

 

l        FILENAME

 

FILENAME用以表示目前正在处理的文件档名.

 

l        FS

 

栏位分隔字符. 

 

l        $0

 

表示目前awk所读入的数据行. 

 

l        $1,$2..

 

分別表示所读入的数据行之第一栏, 第二栏,..

 

说明:

 

当awk读入一笔数据行 "A123  8:15" 时,会先以$0 记录.

 

故 $0 = "A123  8:15"

 

若程序中进一步使用了 $1, $2.. 或 NF 等內建变量时, awk才会自动分割 $0. 

 

以便取得栏位相关的资料. 切割后各个栏位的资料会分別以$1, $2, $3...予以记录.

 

awk內定(default)的 栏位分隔字符(FS) 为 空白字符(空格及tab).

 

以本例而言, 读者若未改变 FS, 则分割后: 

 

第一栏($1)="A123",  第二栏($2)="8:15".

 

使用者可用正则表达式自行定义 FS. awk每次需要分割数据行时, 会参考目前FS的值.

 

例如 : 

 

令 FS = "[ :]+" 表示任何由 空白" " 或 冒号":" 所组成的字串都可当成分隔字符, 则分割后 :   

 

第一栏($1) = "A123", 第二栏($2) = "8", 第三栏($3) = "15"

 

l        NR

 

NR 表从 awk 开始执行该程序后所读取的数据行数.

 

l        FNR

 

FNR 与 NR 功用类似. 不同的是awk每打开一个新的文件,FNR 便从 0 重新累计

 

l        NF

 

NF表目前的数据行所被切分的栏位数.

 

awk 每读入一笔资料后, 在程序中可以 NF 来得知该行数据包含的栏位个数.在下一笔资料被读入之前, NF 并不会改变. 但使用者若自行使用$0来记录数据,例如: 使用 getline , 此时 NF 将代表新的 $0 上所记载的资料的栏位个数.

 

l        OFS

 

OFS输出时的栏位分隔字符. 预设值 " "(一个空白), 详见下面说明.

 

l        ORS

 

ORS输出时数据行的分隔字符. 预设值 "/n"(跳行), 见下面说明.

 

l        OFMT

 

OFMT数值资料的输出格式. 预设值 "%.6g"(若须要时最多印出6位小数)

 

当使用 print 指令一次印出多项资料时,

 

例如 : print $1, $2 

 

输出时, awk会自动在 $1 与 $2 之间补上一个 OFS 之值

 

每次使用 print 输出后, awk会自动补上 ORS 之值.

 

使用 print 输出数值数据时, awk将采用 OFMT 之值为输出格式.

 

例如 : 

 

$ awk 'BEGIN { print 2/3,1; OFS=":"; OFMT="%.2g"; print 2/3,1 }'

 

输出:

 

0.666667 1 

 

0.67:1 

 

程序中通过改变OFS和OFMT的值, 改变了指令 print 的输出格式.  

 

l        RS

 

RS( Record Separator) : awk从文件上读取资料时, 将根据 RS 的定义把资料切割成许多Records,而awk一次仅读入一个Record,以进行处理.

 

RS 的预设值是 "/n". 所以一般 awk一次仅读入一行资料. 

 

有时一个Record含括了几行资料(Multi-line Record). 这情況下不能再以"/n"

 

来分隔相邻的Records, 可改用 空白行 来分隔.

 

在awk程式中,令 RS = "" 表示以 空白行 来分隔相邻的Records.

 

l        RSTART

 

RSTART与使用字串函数 match( )有关的变量,详见下面说明.

 

l        RLENGTH

 

RLENGTH与使用字串函数match( )有关之变量.

 

当使用者使用 match(...) 函数后, awk会将 match(...) 执行的结果以RSTART,RLENGTH 记录.

 

请参考 附录 C awk的內建函数 match().

 

l        SUBSEP

 

SUBSEP(Subscript Separator) 数组下标的分隔字符, 

 

预设值为"/034"实际上, awk中的 数组 只接受 字串 当它的下标,如: Arr["John"].

 

但使用者在 awk 中仍可使用 数字 当阵列的下标, 甚至可使用多维的数组(Multi-dimenisional Array) 如: Arr[2,79] 

 

事实上, awk在接受 Arr[2,79] 之前, 就已先把其下标转换成字串"2/03479", 之后便以Arr["2/03479"] 代替 Arr[2,79].

 

可参考下例 :

 

awk 'BEGIN { 

 

Arr[2,79] = 78

 

print  Arr[2,79]

 

print  Arr[ 2 , 79 ]

 

print  Arr["2/03479"]

 

idx = 2 SUBSEP 79

 

print Arr[idx]

 

}

 

' $*

 

执行结果输出:

 

78

 

78

 

78

 

78

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值