《Linux命令行与shell脚本编程大全》第二十二章 gawk进阶

gawk是一门功能丰富的编程语言,你能够经过它所提供的各类特性来编写好几程序处理数据。 linux

22.1 使用变量

gawk编程语言支持两种不一样类型的变量:正则表达式

内建变量和自定义变量shell

 

22.1.1 内建变量

gawk程序使用内建变量来引用程序数据里的一些特殊功能编程

 

1.字段和记录分隔符变量数组

数据字段变量:容许你使用美圆符和字段在该记录中的位置值来引用记录对应的字段。bash

要引用第一个字段就用变量$1,第二个就用$2,….以此类推。编程语言

 

数据字段是由分隔符来划定的。默认字段分隔符是一个空白字符,也就是空格或者制表符。函数

 

有一组内建变量用于控制gawk如何处理输入输出数据中的字段和记录,见下表:spa

变量命令行

描述

FIELDWIDTHS

有空格分隔的一列数字,定义每一个数据字段的确切宽度

FS

输入字段分隔符

RS

输入记录分隔符

OFS

输出字段分隔符

ORS

输出记录分隔符

 

1)print命令会自动将OFS变量的值放置在输出中的每一个字段间。

实例:

xcy@xcy-virtual-machine:~/shell/22zhang$ cat data1

data11,data12,data13,data14

data21,data22,data23,data24

data31,data32,data33,data34

data41,data42,data43,data44

data51,data52,data53,data54

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS=","; OFS="-"} {print $1,$2,$3}' data1

data11-data12-data13

data21-data22-data23

data31-data32-data33

data41-data42-data43

data51-data52-data53

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS=","; OFS="<-->"} {print $1,$2,$3}' data1

data11<-->data12<-->data13

data21<-->data22<-->data23

data31<-->data32<-->data33

data41<-->data42<-->data43

data51<-->data52<-->data53

xcy@xcy-virtual-machine:~/shell/22zhang$

 

2) FIELDWIDTHS变量容许你不依靠字段分割符来读取记录。一旦这是了FILEDWIDTFS变量,gawk就会忽略FS变量。

警告:一旦设定了FIELDWIDTHS变量的值,就不能再改变了。这种方法并不适用于变长的字段

 

有写数据没有指定分隔符,而是放在特定的列,这时候就能够用FIELDWIDTHS了:

例子:

xcy@xcy-virtual-machine:~/shell/22zhang$ cat data2

1005.3246782.37

115-2.343324.08

05828.3452433.1

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FIELDWIDTHS="3 5 2 5"} {print $1,$2,$3,$4}' data2

100 5.324 67 82.37

115 -2.34 33 24.08

058 28.34 52 433.1

xcy@xcy-virtual-machine:~/shell/22zhang$

 

3)RS和ORS定义了gawk程序如何处理数据流中的字段。默认这两个都是换行符

默认的RS代表,输入数据流中的每行新文本就是一条新记录

例子:

xcy@xcy-virtual-machine:~/shell/22zhang$ cat data3

kobe bryant

24 Los Lakers

Los, road34

99038

 

Paul Gaoso

15 los Lakers

Los, road 38

23123

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS="\n";RS=""} {print $1, $4}' data3

kobe bryant 99038

Paul Gaoso 23123

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS="\n";RS=""} {print $1, $2}' data3

kobe bryant 24 Los Lakers

Paul Gaoso 15 los Lakers

xcy@xcy-virtual-machine:~/shell/22zhang$

 

上面的例子中,4行才是一条记录,因此指定FS=”\n”

每行只是一个字段。

如何判断一个新的数据行的开始:解决方法计算RS变量设为空。而后在数据记录之间留一个空白行。gawk会把每一个空白行当作一个记录分隔符。

 

说明:

默认的字段分隔符是空格,记录分割符是换行符

上面的例子把字段分割符改为了换行符,记录分隔符编程了空白行(RS=””

 

2. 数据变量

还有一些其余的内建变量:

变量

描述

ARGC

当前命令行参数个数

ARGIND

当前文件在ARGV的位置

ARGV

包含命令行参数的数组

CONVFMT

数字的转换格式,模式是%.6 g

ENVIRON

当前shell环境变量及其值组成的关联数组

ERRNO

当读取或关闭文件发生错误时的系统错误号

FILENAME

用做输入数据的数据文件的文件名

FNR

当前数据文件的数据行数

IGNORECASE

设成非零值,忽略gawk命令中出现的字符串的字符大小写

NF

数据文件中的字段总数

NR

已处理的输入记录数

OFMT

数字的输出格式,默认值%.6 g

RLENGTH

由match函数所匹配的字符串的长度

RSTART

由match函数所匹配的字符串的起始位置

 

实例1:

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{print ARGC,ARGV[1]}' data2

2 data2

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{print ENVIRON["HOME"]}'

/home/xcy

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{print ENVIRON["HOME"]; print ENVIRON["PATH"]}'

/home/xcy

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/sbin/:/usr/bin:/usr/sbin:/home/xcy/Bt_A7/Bt_A7/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin

xcy@xcy-virtual-machine:~/shell/22zhang$

 ENVIRON[“HOME”] 从系统中提取HOME环境变量的值。

 

例子2:

当要在gawk程序中跟踪数据字段和记录时,变量FNR,NF和NR就很是方便了。

NF变量能够在你不知道具体位置的状况下指定记录中的最后一个数据字段:

$gawk ‘BEGIN{FS=”:”; OFS=”:”} {print $1, $NF}’ /etc/passwd

假设NF为7,那么至关因而$7。打印最后一个字段

 

例子3:

FNR变量含有当前数据文件中已处理过的记录数

NR变量则含有已处理过的记录总数

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS=","} {print $1,"FNR="FNR}' data1

data11 FNR=1

data21 FNR=2

data31 FNR=3

data41 FNR=4

data51 FNR=5

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS=","} {print $1,"FNR="FNR, "NR="NR} END{print "There were ",NR," recordes"}' data1 data1

data11 FNR=1 NR=1

data21 FNR=2 NR=2

data31 FNR=3 NR=3

data41 FNR=4 NR=4

data51 FNR=5 NR=5

data11 FNR=1 NR=6

data21 FNR=2 NR=7

data31 FNR=3 NR=8

data41 FNR=4 NR=9

data51 FNR=5 NR=10

There were  10  recordes

xcy@xcy-virtual-machine:~/shell/22zhang$

 

当处理第2个文件时,FNR又被置成1了,可是NR仍是继续增长的。

 

注意:

1)在shell脚本中使用gawk时,应该将gawk的命令放到不一样的行,便于理解和阅读

2)若是在不一样的shell脚本中使用了相同的gawk脚本,应该把gawk放在一个单独的文件中。再用-f参数去引用它。

 

 

22.1.2自定义变量

变量名能够是字母下划线开头,还能够有数字。而且变量名区分大小写

1.在脚本中给变量赋值

能够对变量进行修改,能够进行数学运算

例子:

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk '

> BEGIN{

> test="hahaha, i am test"

> print test}'

hahaha, i am test

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk '

BEGIN{

test="hahaha, i am test"

print test

> test=156

> print test

> }'

hahaha, i am test

156

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk '

> BEGIN{

> x=4

> x=x*3+4

> print x

> }'

16

xcy@xcy-virtual-machine:~/shell/22zhang$

 

2. 在命令行上给变量赋值

也能够用gawk命令行来给程序中的变量赋值。这容许你在正常的代码以外赋值。

xcy@xcy-virtual-machine:~/shell/22zhang$ cat script

BEGIN{FS=","}

{print $n}

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script n=3 data1

data13

data23

data33

data43

data53

xcy@xcy-virtual-machine:~/shell/22zhang$

上面能够给n进行赋值,改变脚本的行为。

这样能够在不改变脚本代码的状况下就能改变脚本的行为

上面这样存在的问题是设置的变量在代码的BEGIN部分不可用

 

解决方法,用-v参数。它容许你在BEGIN代码以前设定变量,要放在脚本代码以前。

xcy@xcy-virtual-machine:~/shell/22zhang$ cat script2

BEGIN{print "The starting value is",n; FS=","}

{print $n}

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -v n=4 -f script2 data1

The starting value is 4

data14

data24

data34

data44

data54

xcy@xcy-virtual-machine:~/shell/22zhang$

 

22.2 处理数组

gawk编程语言使用关联数组提供数组功能

关联数组跟数字数组不一样之处在于它的索引值能够是任意文本字符串。

不须要用连续的数字来标识数组元素。关联数组用各类字符串来引用值

每一个索引字符串都必须可以惟一标识赋给它的数据元素

 

22.2.1 定义数组变量

用标准赋值语句来定义数组变量。格式以下:

var[index]=element

var是变量名,index是关联数组的索引值 element是数据元素值

例子:

这里要加双引号,数字不用加,字符串须要加

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk '                     

BEGIN{

nba["kobe"]="bryant"

nba["cp3"]="paul"

print nba["kobe"]

print nba["cp3"]

}'

bryant

paul

# 还能够进行数学运算。

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk '

> BEGIN{

> arr[1]=99

> arr[2]=77

> total=arr[1] + arr[2]

> print "total =",total

> }'

total = 176

xcy@xcy-virtual-machine:~/shell/22zhang$

 

 

22.2.2 遍历数组变量

关联数组的索引能够是任何东西

遍历数组能够用for语句的一种特殊形式:

for (var in array)

{

  statements

}

这个for语句会在每次循环时都将关联数组array的下一个索引值赋值给变量var,而后执行一遍statements

xcy@xcy-virtual-machine:~/shell/22zhang$ cat script3

BEGIN{

var["a"]="hahah"

var["b"]=2

var["c"]="yutong keche"

var["d"]=4

 

 

for (test in var)

{

         print "Index:",test," - Value:",var[test]

}

}

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script3

Index: a  - Value: hahah

Index: b  - Value: 2

Index: c  - Value: yutong keche

Index: d  - Value: 4

xcy@xcy-virtual-machine:~/shell/22zhang$

 

22.2.3删除数组变量

格式以下:

delete array[index]

删除之后就没办法再用它来提取元素值了。

好比:

xcy@xcy-virtual-machine:~/shell/22zhang$ cat script4

BEGIN{

var["a"]="hahah"

var["b"]=2

var["c"]="yutong keche"

for (test in var)

{

         print "old: Index:",test," - Value:",var[test]

}

print "Now,delete array:"

delete var["c"]

 

for (test in var)

{

         print "new: Index:",test," - Value:",var[test]

}

}

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script4

old: Index: a  - Value: hahah

old: Index: b  - Value: 2

old: Index: c  - Value: yutong keche

Now,delete array:

new: Index: a  - Value: hahah

new: Index: b  - Value: 2

xcy@xcy-virtual-machine:~/shell/22zhang$

 

22.3 使用模式

gawk支持多种类型的匹配模式来过滤数据记录。

BEGIN和END关键字用来读取数据流以前或以后执行命令的特殊模式

 

22.3.1 正则表达式

能够用基础正则表达式(BRE)或扩展正则表达式(ERE)来选择程序脚本做用在数据流中的哪些行上。

 

使用正则表达式时,正则表达式必须出如今它要控制的程序脚本的左花括号前。

xcy@xcy-virtual-machine:~/shell/22zhang$ cat script5

BEGIN{FS=","}

/11/{print $1, $2}

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script5 data1

data11 data12

xcy@xcy-virtual-machine:~/shell/22zhang$

正则表达式/11/匹配了字段中含有字符串11的记录。

 

 

22.3.2 匹配操做符

匹配操做符容许将正则表达式限定在记录中的特定数据字段。匹配操做符是~。

能够指定匹配操做符,数据字段变量以及要匹配的正则表达式

$1 ~ /^data/

$1变量表明记录中的第一个数据字段。

上面的例子会过滤出以data开头的全部记录。

取反: $1 !~ /^data1/   匹配第一个字段不以data1开头的记录

例子2:

// 匹配第2个字段为data2开头的记录,而且打印第1和第3个字段。$2表示第2个字段

xcy@xcy-virtual-machine:~/shell/22zhang$ cat data1

data11,data12,data13,data14

data21,data22,data23,data24

data31,data32,data33,data34

data41,data42,data43,data44

data51,data52,data53,data54

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS=","} $2 ~ /^data2/{print $1, $3}' data1   data21 data23

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS=","} $2 !~ /^data2/{print $1, $3}' data1  // 这里还能够取反,匹配第二个字段不以data2开头的记录。加个感叹号

data11 data13

data31 data33

data41 data43

data51 data53

xcy@xcy-virtual-machine:~/shell/22zhang$

 

例子3:

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS=":"} $1 ~ /^xcy/{print $1,":" $NF}' /etc/passwd

xcy :/bin/bash

xcy@xcy-virtual-machine:~/shell/22zhang$

 

例子4:! 用来排除正则表达式中的匹配

$ gawk -F: '$1 !~ /^xcy|^root/{print $1, ":" $NF}' /etc/passwd

-F 用来指定主句字段的分隔符

上面代表过滤第一个字段不以xcy开头,或不以root开头。

 

22.3.3 数学表达式

还能够在匹配模式中用数学表达式。

例子:想显示全部属于root用户组(组ID为0)的系统用户

$gawk –F: ‘$4 == 0{print $1}’ /etc/passwd

还能够用任何常见的数学比较表达式: ==  <=  >=  >  <

 

匹配字符串:注意这时候是彻底匹配

$gawk –F, ‘$1==”data” {print $1}’ data1

第一个字段必须是data,而不是包含data

 

22.4 结构化命令

 

22.4.1 if语句

给if语句定义一个求值的条件,并将其用圆括号括起来。

条件为真在if后面的语句就会执行。

还能够接上else。和C语言的差很少

例子:

xcy@xcy-virtual-machine:~/shell/22zhang$ cat data4

3

5

34

467

1

xcy@xcy-virtual-machine:~/shell/22zhang$ cat ifscript

{

         if ($1 > 29)

         {

                   print "$1 > 29"  # 多条命令须要用{}括起来

                   print $1

         }

         else if($1 == 3) 

         {

                   print "step 2 $1 == 3"

         }       

         else

         {

                   print "step 3 "

         }

}

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f ifscript data4

step 2 $1 == 3

step 3

$1 > 29

34

$1 > 29

467

step 3

xcy@xcy-virtual-machine:~/shell/22zhang$

 

还能够在单行上使用else子句,这样就须要在if后面接上分号;

$ gawk '{if($1 == 3) print $1" == 3 "; else print $1,"!= 3"}' data4

 

22.4.2 while 语句

基本格式:

while (condition)

{

  statement

}

 

while里面还能够放break和continue。用起来跟C语言同样

 

例子:

xcy@xcy-virtual-machine:~/shell/22zhang$ cat data5

100 110 120

170 180 190

300 310 320

xcy@xcy-virtual-machine:~/shell/22zhang$ cat script6

{

total=0

i=1

while(i < 4)

{

         total += $i

         i++

         if(i==3)

         {

                   break

                   #continue

         }

         print "i=", i

}

avg=total/3

print "Average:",avg

}

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script6 data5

i= 2

Average: 70

i= 2

Average: 116.667

i= 2

Average: 203.333

xcy@xcy-virtual-machine:~/shell/22zhang$

 

 

 

22.4.3 do-while语句

和while语句相似,可是会在检查条件语句以前执行命令。格式以下:

do

{

  statement

} while(condition)

 

这种格式保证了语句在条件被求值以前至少执行一次

例子:

xcy@xcy-virtual-machine:~/shell/22zhang$ cat script7

{

total=0

i=1

do

{

         total += $i

         i++

} while(total < 300)

print "total:",total,"i=",i

}

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script7 data5

total: 330 i= 4

total: 350 i= 3

total: 300 i= 2

xcy@xcy-virtual-machine:~/shell/22zhang$

 

22.4.4 for语句

支持C风格的for循环:

例子:

xcy@xcy-virtual-machine:~/shell/22zhang$ cat script8

{

total=0

for(i=1; i<4; i++)

{

         total += $i

}

avg=total/3

print "Total:",total,"Average:",avg

}

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script8 data5

Total: 330 Average: 110

Total: 540 Average: 180

Total: 930 Average: 310

xcy@xcy-virtual-machine:~/shell/22zhang$

 

 

22.5 格式化打印

print打印在如何显示数据上并未提供多少控制。

下面介绍一个格式化打印命令,printf,和C语言的那个有点相似:

printf “format string” ,var1,var2…

前面也是格式化命令。跟C语言很像:

1)

%c 输出字符, %d 整数值, %i 整数值,%e 用科学计数法显示数

%f 浮点数,%g 科学计数法或浮点数显示(较短的)

%o 八进制,%s 字符串

%x 十六进制小写,%X 十六进制大写

2)

还有三种修饰符能够用来进一步控制输出

width:指定输出字段最小宽度的数字值。实际比这短,则会补充空格,不然按正常输出

prec:指定浮点数中小数点后面的位数。或者文本字符串中显示的最大字符数

-(减号):指明在格式化空间中放入数据时采用左对齐,而不是右对齐

例子:

$ cat data3

kobe bryant

24 Los Lakers

Los, road34

99038

 

Paul Gaoso

15 los Lakers

Los, road 38

23123

$ gawk 'BEGIN{FS="\n"; RS=""} {printf "%s %s\n", $1,$2}' data3  #正常输出

kobe bryant 24 Los Lakers

Paul Gaoso 15 los Lakers

$ gawk 'BEGIN{FS="\n"; RS=""} {printf "%16s %s\n", $1,$2}' data3  #指定输出字段最小宽度

     kobe bryant 24 Los Lakers

      Paul Gaoso 15 los Lakers

$ gawk 'BEGIN{FS="\n"; RS=""} {printf "%-16s %s\n", $1,$2}' data3  #指定左对齐

kobe bryant      24 Los Lakers

Paul Gaoso       15 los Lakers

还能够指定浮点数格式

… {printf “%5.1f\n”, avg} …

占5位,小数点后只显示一位。

 

22.6 内建函数

gawk提供了很多内建的函数,能够进行常见的数学 字符串以及时间函数运算

 

22.6.1 数学函数

函数

描述

atan2(x,y)

x/y的反正切,x y以弧度为单位

cos(x)

X的余弦 x以弧度为单位

exp(x)

X的指数函数

int(x)

X的整数部分,取靠近零一侧的值

log(x)

X的天然对数

rand(x)

比0大比1小的随机浮点数

sin(x)

正弦,x以弧度为单位

sqrt(x)

X的平方根

srand(x)

为计算随机数指定一个种子值

and(v1,v2)

执行v1和v2的按位与运算

compl(val)

执行val的补运算

lshift(val,count)

Val的值左移count位

or(v1,v2)

V1和v2的按位或运算

rshift(val,count)

Val右移count位

xor(v1,v2)

V1和v2的异或运算

 

例子:

$ gawk 'BEGIN{x=rand(); print "x =",x}'

$gawk 'BEGIN{x=int(-7.6); print "x =",x}'

$ gawk 'BEGIN{x=sin(1.57); print "x =",x}'

$ gawk 'BEGIN{x=int(10*rand()); print "x =",x}'

$ gawk 'BEGIN{x=and(1,2); print "x =",x}'

$ gawk 'BEGIN{x=lshift(1,2); print "x =",x}'

$ gawk 'BEGIN{x=xor(1,2); print "x =",x}'

 

22.6.2 字符串函数

 

函数

描述

asort(s [,d])

将数组s按数据元素值排序。索引值会被替换成表示新的排序顺序的连续数字。另外若是指定了d,则排序后的数组会存储在数组d中。

asorti(s [,d])

将数组s按索引值排序。生成的数组会将索引值做为数据元素值,用连续数字因此来代表排序顺序。若指定了d,排序后是数组会存在d中

gensub(r,s,h [,t])

查找变量$0或目标字符串t(若提供的话)来匹配正则表达式r。

若是h是一个以g或G开头的字符串,就用s替换掉匹配的文本。

若是h是数字,它表示要替换掉的第h处r匹配的地方

gsub(r,s [,t])

查找变量$0或目标字符串t(若提供的话)来匹配正则表达式。

若是找到了就所有替换成字符串s

index(s,t)

返回字符串t在字符串s中的索引值。若是没找到返回0

length([s])

返回字符串s的长度,若是没有指定的话返回$0的长度

match(s, r [,a])

返回字符串s中正则表达式r出现位置的索引。若指定数组a,则会存储s中匹配正则表达式的那部分

split(s, a [,r])

将s用FS字符或正则表达式r(若指定的话)分开放到数组a中。返回字段总数

sprintf(format,variables)

用提供的format和variables返回一个相似于printf输出的字符串

sub(r,s [,t])

在变量$0或目标字符串t中查找正则表达式t的匹配。若找到了,就用字符串s替换掉第一处匹配

substr[s,i [,n]]

返回s从索引值i开始的n个字符组成的字符串。若未提供n,则返回s剩下的部分

tolower(s)

所有转小写

toupper(s)

所有转大写

 

 

有些用起来比较简单,好比大小写,求长度

$ gawk 'BEGIN{x=length("chong"); print "x =",x}'

$ gawk 'BEGIN{x=toupper("chong"); print "x =",x}'

 

下面是asort的例子:

xcy@xcy-virtual-machine:~/shell/22zhang$ cat script9

BEGIN{

var["a"]=177

var["b"]=9

var["c"]=3

var["d"]=4444

var["e"]=566

asort(var,test)

for (i in test)

{

         print "Index:",i,"-value:",test[i]

}

}

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script9

Index: 4 -value: 566

Index: 5 -value: 4444

Index: 1 -value: 3

Index: 2 -value: 9

Index: 3 -value: 177

xcy@xcy-virtual-machine:~/shell/22zhang$

注意看对var数组的数据元素进行排序了。排序后的数组放在test数组里面了。

索引值被替换成了数字。索引最大的对应数据元素也是最大的。

 

下面是split的例子:

xcy@xcy-virtual-machine:~/shell/22zhang$ cat data1

data11,data12,data13,data14

data21,data22,data23,data24

data31,data32,data33,data34

data41,data42,data43,data44

data51,data52,data53,data54

xcy@xcy-virtual-machine:~/shell/22zhang$ cat script10

BEGIN{

FS=","

}

{

count=split($0,test)

for (i in test)

{

         print "Index:", i, "-Value:",test[i]

}

print "count =",count

#print test[1], test[5]

}

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script10 data1

 

将每一行用FS字符(,)分开,放到了test数组上。再打印数组的数据。

count表示字段总数

22.6.3 时间函数

函数

描述

mktime(datadpace)

将一个按YYYYMMDDHHMMSS[DST]格式指定的日期转成时间戳值

strftime(format [,timestamp])

将当前时间的时间戳或timestamp(若提供的话)转化格式化日期(采用shell函数data()的格式)

systime()

返回当前时间的时间戳

 

例子:

xcy@xcy-virtual-machine:~/shell/22zhang$ cat script11

BEGIN{

date=systime()

day=strftime("%A, %B %d, %Y",date)

print day

}

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script11

星期六, 十一月 25, 2017

xcy@xcy-virtual-machine:~/shell/22zhang$

 注意:BEGIN后面的{要挨着BEGIN写,不能换行写。

不然报错

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script11

gawk: script11:2: BEGIN 块必须有一个行为部分

22.7 自定义函数

22.7.1 定义函数

必需要用function关键字,格式以下:

function name([variables])

{

  statement

}

函数名必须可以统一标识函数。能够在调用的gawk程序中传给这个函数一个或多个变量

 

例子:

// 打印记录中的第三个字段

function printthird()

{

  print $3

}

 

还能够用return返回值。

例子:

function myrand(limit)

{

  return int(limit * rand())

}

用法:

x=myrand(100)

 

22.7.2 使用自定义函数

定义函数时,它必须出如今全部代码块以前(包括BEGIN代码块)。

实例:

xcy@xcy-virtual-machine:~/shell/22zhang$ cat data3

kobe bryant

24 Los Lakers

Los, road34

99038

 

Paul Gaoso

15 los Lakers

Los, road 38

23123

xcy@xcy-virtual-machine:~/shell/22zhang$ cat fun1

function myprint()

{

         print "This is myprint() +++"

         printf "%-16s - %s\n", $1,$4

}

BEGIN{

FS="\n"

RS=""

}

{

myprint()

}

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f fun1 data3

This is myprint() +++

kobe bryant      - 99038

This is myprint() +++

Paul Gaoso       - 23123

xcy@xcy-virtual-machine:~/shell/22zhang$

 

先格式化记录中的第一个和第四个数据字段。再输出

定义了函数就能够在程序的代码中随便使用了

 

22.7.3 建立函数库

能够将多个函数放到一个库文件中,这样就能在全部的gawk程序中使用了。

步骤:

1)先建立一个存储全部gawk函数的文件

xcy@xcy-virtual-machine:~/shell/22zhang$ cat funlib

function mylib()

{

         print "mylib() +++"

}

function myprint()

{

         printf "%-16s - %s\n",$1,$4

}

function myrand(limit)

{

         return int(limit * rand())

}

function printthird()

{

         print $3

}

2)就能够在脚本中使用啦

xcy@xcy-virtual-machine:~/shell/22zhang$ cat usefunlib

BEGIN{

FS="\n"

RS=""

}

{

myprint()

}

xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f funlib -f usefunlib data3

kobe bryant      - 99038

Paul Gaoso       - 23123

xcy@xcy-virtual-machine:~/shell/22zhang$

要引用文件须要使用-f参数。能够在同一命令行中使用多个-f参数。

 

22.8 实例

假设有一个数据文件,里面有两支队伍每队2我的,每人3次的比赛成绩。要求总成绩和平均成绩:

xcy@xcy-virtual-machine:~/shell/22zhang$ cat scores.txt

Rich Blum,team1,100,115,99

Bar Blum,team1,110,118,114

Chr Bre,team2,120,80,90

Tim Bre,team2,125,70,60

 

下面是脚本:

xcy@xcy-virtual-machine:~/shell/22zhang$ cat bowling.sh

#!/bin/bash

for team in $(gawk -F, '{print $2}' scores.txt | uniq)

do

#       echo "team: $team"

         gawk -v team=$team 'BEGIN{FS=",";total=0}

         {

#                print "step1+++"

                   if ($2==team)

                   {

                            total += $3 + $4 + $5;

                   }

         }

         END{

                   avg = total / 6;

                   print "Total for",team,"is",total,"The avgarge is",avg

         }' scores.txt

done

脚本分析:

1)注意uniq这个关键字,这里能够排除同样的。for语句是用来筛选队名的。

2)for循环里面,假如队名是team1,那么就先处理team1。会读取全部记录,将队名都为team1的记录的$3 $4 $5相加,就是总成绩了。最后求平均值

 

这里是运行状况:

xcy@xcy-virtual-machine:~/shell/22zhang$ ./bowling.sh

Total for team1 is 656 The avgarge is 109.333

Total for team2 is 545 The avgarge is 90.8333

相关文章
相关标签/搜索