标签:需要 特殊 实例 cat 补充 nba fun 比赛 必须
gawk是一门功能丰富的编程语言,你可以通过它所提供的各种特性来编写好几程序处理数据。
gawk编程语言支持两种不同类型的变量:
内建变量和自定义变量
gawk程序使用内建变量来引用程序数据里的一些特殊功能
1.字段和记录分隔符变量
数据字段变量:允许你使用美元符和字段在该记录中的位置值来引用记录对应的字段。
要引用第一个字段就用变量$1,第二个就用$2,….以此类推。
数据字段是由分隔符来划定的。默认字段分隔符是一个空白字符,也就是空格或者制表符。
有一组内建变量用于控制gawk如何处理输入输出数据中的字段和记录,见下表:
变量 |
描述 |
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参数去引用它。
变量名可以是字母下划线开头,还可以有数字。并且变量名区分大小写
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$
gawk编程语言使用关联数组提供数组功能
关联数组跟数字数组不同之处在于它的索引值可以是任意文本字符串。
不需要用连续的数字来标识数组元素。关联数组用各种字符串来引用值
每个索引字符串都必须能够唯一标识赋给它的数据元素
用标准赋值语句来定义数组变量。格式如下:
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$
关联数组的索引可以是任何东西
遍历数组可以用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$
格式如下:
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$
gawk支持多种类型的匹配模式来过滤数据记录。
BEGIN和END关键字用来读取数据流之前或之后执行命令的特殊模式
可以用基础正则表达式(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的记录。
匹配操作符允许将正则表达式限定在记录中的特定数据字段。匹配操作符是~。
可以指定匹配操作符,数据字段变量以及要匹配的正则表达式
$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开头。
还可以在匹配模式中用数学表达式。
例子:想显示所有属于root用户组(组ID为0)的系统用户
$gawk –F: ‘$4 == 0{print $1}’ /etc/passwd
还可以用任何常见的数学比较表达式: == <= >= > <
匹配字符串:注意这时候是完全匹配
$gawk –F, ‘$1==”data” {print $1}’ data1
第一个字段必须是data,而不是包含data
给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
基本格式:
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$
和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$
支持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$
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位,小数点后只显示一位。
gawk提供了不少内建的函数,可以进行常见的数学 字符串以及时间函数运算
函数 |
描述 |
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}‘
函数 |
描述 |
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表示字段总数
函数 |
描述 |
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 块必须有一个行为部分
必须要用function关键字,格式如下:
function name([variables])
{
statement
}
函数名必须能够统一标识函数。可以在调用的gawk程序中传给这个函数一个或多个变量
例子:
// 打印记录中的第三个字段
function printthird()
{
print $3
}
还可以用return返回值。
例子:
function myrand(limit)
{
return int(limit * rand())
}
用法:
x=myrand(100)
定义函数时,它必须出现在所有代码块之前(包括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$
先格式化记录中的第一个和第四个数据字段。再输出
定义了函数就可以在程序的代码中随便使用了
可以将多个函数放到一个库文件中,这样就能在所有的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参数。
假设有一个数据文件,里面有两支队伍每队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
《Linux命令行与shell脚本编程大全》第二十二章 gawk进阶
标签:需要 特殊 实例 cat 补充 nba fun 比赛 必须
原文地址:http://www.cnblogs.com/xcywt/p/8011052.html