sed与awk菜鸟的笔记--第九章 函数

第九章 函数

awk有很多内置函数,分为算术函数和字符串函数两种.也可以用户自定义函数.

 

算术函数

cos(x):返回x的余弦(x为弧度)

sin(x)返回x的正弦(x为弧度)

atan2(y,x):返回y/x的反正切,其值在-π到π之间

exp(x):返回e的x次幂

int(x):返回x的整数部分值

log(x):返回x的自然对数(以e为底)

sqrt(x):返回x的平方根

rand():返回伪随机数r,其中0<=r<1

srand(x):建立rand()的新的种子数.如果没有指定种子数,就用当天的时间.返回旧的种子值.

 

 

整数函数

函数int()将小数点后吗的数字舍去,没有四舍五入.(使用printf格式"%.0f"实现四舍五入)

 

$ echo a | awk '{print 10/3}'                    

3.33333

 

$ echo a | awk '{print 8/3}'     

2.66667

 

$echo a | awk '{print int(8/3)}'       

2

 

$ echo a | awk '{printf ("%.0f\n",8/3)}'

3

 

 

随机数的生成

 

如果没有调用srand(),awk在开始执行程序之前默认为以某个参数调用srand(),使得程序在每次运行时都以同一个种子数开始.

这可以用于重复测试相同的操作.

下面例子,如果不指定srand(),每次先运行rand()时都是同一个数.

$ echo a | awk '{print rand();srand();print rand()}'

0.237788

0.772482

 

$ echo a | awk '{print rand();srand();print rand()}'

0.237788

0.265938

 

 

彩票选号(35选7)

下例将实现代码写成awk脚本,用shell脚本调用

awk脚本需要输入两个参数,TOPNUM选NUM(默认35选7)

所有操作要在BEGIN中执行,程序中没有其他语句.所以要用-v指定参数,在完成BEGIN后推出awk.

 

$ cat lotto.sh

#!/bin/bash

awk -v NUM=$1 -v TOPNUM=$2 -f lotto.awk

 

$ cat lotto.awk 

BEGIN{

        if (NUM <= 0)

                NUM = 7

        if (TOPNUM <= 0)

                TOPNUM = 35

        printf("Pick %d of %d\n",NUM,TOPNUM)

        srand()

        for (j = 1; j <=NUM; ++j){

                do {

                        select = 1 + int(rand()*TOPNUM)

                }while (select in pick)

                pick[select] = select

        }

        for (j in pick)

                printf ("%s ",pick[j])

        printf("\n")

}

 

$ sh lotto.sh 7 35

Pick 7 of 35

35 27 18 8 21 23 3 

 

 

字符串函数

 

index(s,t):返回字串t在字符串s中的位置,如果没指定s,则返回0.

length(s):返回字符串s的长度,如果没给出s,则返回$0的长度(即输入行长度).

match(s,r):如果正则表达式r在s中出现,则返回起始位置.如果不匹配,则返回0.设置RSTART和RLENGTH的值.

split(s,a,sep):以分隔符sep将s分解到数组a中,返回元素个数.如果没给sep,默认为FS.

sprintf("fmt",expr):对expr使用print格式说明.

sub(r,s,t):在字符串t中用s替换正则表达式r的首次匹配.成功返回1,否则返回0.若没给出t,默认为$0.

gsub(r,s,t):在字符串t中,用s替换正则表达式r匹配的所有字符串,并返回替换个数.如果没有给出t,默认为$0.

substr(s,p,n):返回字符串s中从位置p开始长度为n的字串,如果没给出n或n长度大于从p到字符串结尾的长度,则返回从p开始到结尾的字符串.

tolower(s):将字符串s所有大写字符转换为小写,并返回新串.

toupper(s):将字符串s所有小写字符转换为大写,并返回新串.

 

 

子串:

index()和substr()都用于处理子串.

index(s,t)字符串开始位置是1(和c语言不同,c语言中子串开始位置是0).如果没有发现子串,函数返回0.

$ echo abcdefg | awk '{print index("asdg","dg")}'

3

$ echo abcdefg | awk '{print index("asdg","e")}' 

0

substr(s,p)返回字符串s中从p开始的所有字符.

$  echo abcdefg | awk '{print substr($1,3)}'       

cdefg

 

 

替换函数

sub()和gsub()的区别是:sub()只替换实现的第一个位置.gsub()是全部替换.(和sed中用g标志的替换命令相同).

替换后返回值是替换的数量,而不是替换后的字符串.所以,对于sub()来说,返回值只有0和1,可用其测试是否执行了替换操作.

如果想替换多个,如2个,3个....可用循环,下例中只有两个a,第三次没有了,就只能返回0.

 

$ echo aabbcc | awk '{print sub("a","A",$0);print sub("a","A",$0);print sub("a","A",$0)}'   

1

1

0

 

#awk中的print后面没有表达式则打印出全部,下例是替换后打印全部输入数据

$ echo aabbcc | awk '{gsub("a","A",$0);print}'                      

AAbbcc

 

 

大小写转换

toupper()和tolower().非字母的字符不会发生转换.

 

$ cat name_list 

Tim Duncan      21

Jason Kidd      5

Kevin Garnett   21

 

$ cat name_list | awk '{print "<" toupper($0) ">","<" tolower($0) ">"}'

<TIM DUNCAN     21> <tim duncan 21>

<JASON KIDD     5> <jason kidd  5>

<KEVIN GARNETT  21> <kevin garnett      21>

 

$ cat name_list | awk '{printf("<%s>,<%s>\n",toupper($0),tolower($0))}'

<TIM DUNCAN     21>,<tim duncan 21>

<JASON KIDD     5>,<jason kidd  5>

<KEVIN GARNETT  21>,<kevin garnett      21>

 

 

match(s,r)函数

match(字符串,正则表达式)函数用于确定一个正则表达式是否与字符串匹配.

参数与替换函数的参数顺序容易混淆.替换函数第一个参数是正则,第二个是字符串.match第一个是字符串,第二个是正则.

match()函数也设置了两个系统变量RSTART,RLENGTH.

RSTART包含这个函数的返回值,即匹配字串的开始位置.RLENGTH中包含匹配的字符串的子字符(而不是字串的结束位置).

 

 

自定义函数

 

function name(parameter-list){

statements

[return expression]

}

 

parameter-list是以逗号分隔的多个参数,不需要制定类型

return expression可选,通常返回一个值用于调用

function spurs(NUM){

        for(i=0;i<NUM;i++)

        print "GO SPURS"

        return "WIN"

}

suprs(3) #调用函数spurs(),3为参数

 

 

维护函数库

可以将不同脚本文件分类放置,这样保存函数文件可以方便重用.

 

你可能感兴趣的:(正则表达式,脚本,J#,bash,D语言)