sed与awk菜鸟的笔记--第八章 条件,循环和数组

第八章 条件,循环和数组

awk中的条件与循环结构是借鉴于c语言的.

条件语句

if (expression)

   action1

[else

   action2]

if (x) print x #测试x是否是非0值

if(x==y) print x #测试x是否等于y

if(x~/[yY]|es?/) print x #判断x是否与一个模式匹配

if(x~/^[yY]$|^[yY]es$/) print x #判断x是否是单独的y,Y,yes或Yes

#如果操作是多条语句,要用大括号括起来,awk对大括号和语句位置没有特殊要求(和sed不同),用分号可代替回车,与java也有点像.

#以下三种情况都可以,不过第一种可增加可读性

if(expression){

   statement1

   statement2

}

if(expression) action1

[else action2]

if(expression) action1;[else action2]

条件操作符

expr?action1:action2

?:操作符可以嵌套使用,这样会导致程序不易读.为了清晰,可以将条件括起来,如下:如果ave大于60则通过

grade = (ave>=60)?"Pass":"Fail"

循环

while循环

while(expression)

   action

do循环

do

   action

while(expression)

for循环

for(set_counter;test_counter;increment_counter)

   action

for (i=1;i<=NF;i++) print $i #用于打印出每一个输入行的每个字段

for (i=NF;i>=1;i--) print $i #从最后一个字段到第一个字段反向打印

求阶乘

fact=number

for(x=number-1;x>1;x--)

   fact*=x

fact=number;for(--number;number>1;number--) fact*=number;print fact

影响控制的其他语句

continue:结束当前循环,继续下一次循环

break:退出循环,继续下面的命令

next:能导致读入下一行,并返回到脚本的顶部

exit:退出循环,并将控制移到END规则

数组

array[subscript] = value

#数组不需要指明大小,只需要指明标识符,下面是为名为hello的数组的第[1]个元素赋值"world"

hello[1]="world"

#打印hello的数组的第[1]个元素

print hello[1]

关联数组

可以使用一个字符串作为数组的下标

arr["TEST"]

arr[$1]=$2

访问关联数组的所有元素,variable为一个随意变量名,array为数组名,但这个访问数组是随机的

for(variable in array[])

do something with array[variable]

#下面例子用于打印下标名和内容

for(item  in acro)

   print item,acro[item]

测试数组中的成员资格

in也是一个操作符,用于测试下标是否是数组成员

item in array #如果array[item]存在则返回1,否则返回0

用split()创建数组

内置函数split()能够将任何字符串分解到数组的元素中.

其实split()的作用就是可以更细化输入项,可以把各个输入域再通过分隔符分隔成更小块

n = split(string,array,separator)

string:要被分解的输入字符串

array:指定的数组.数组的下标从1开始到n,n即为数组中元素的个数.

separator:分解元素的分隔符.如果没指定则用默认的FS.它可以是个正则表达式,不仅仅只是一个单个字符.

#以下为对文件name_list的处理,文件名字以空格分隔,名字与号码之间以tab键分隔

$ cat name_list 

Tim Duncan      21

Jason Kidd      5

Kevin Garnett   21

#输入域分隔符是tab键,split()函数分隔符是空格,z为数组包含元素的个数

$ cat name_list | awk 'BEGIN{FS="\t"}{z=split($1,fullname," ");print z,fullname[1],fullname[2]}'

2 Tim Duncan

2 Jason Kidd

2 Kevin Garnett

#输入域分隔符是tab键,split()函数分隔符没有指定,则默认为FS,也为tab键

$ cat name_list | awk 'BEGIN{FS="\t"}{z=split($1,fullname);print z,fullname[1],fullname[2]}'    

1 Tim Duncan 

1 Jason Kidd 

1 Kevin Garnett 

#输入域分隔符是逗号,文件中没有逗号,所以每行只有一个域.split()函数分隔符为tab键,所以数组的第二个元素是号码.

$ cat name_list | awk 'BEGIN{FS=","}{z=split($1,fullname,"\t");print fullname[2]}'  

21

5

21

删除数组元素

将数组中下标为subscript的元素删除

delete array[subscript]

多维数组

array[m,n] #m行n列

awk不支持多为数组,但可以用语法来模拟引用多维数组.

file_array[NR,i] = $1

file_array[2,4] #表示第二行记录的第四个字段值

作为系统变量的数组

ARGV:命令行参数的数组,不包括脚本本身和任何调用awk指定的选项.元素个数可以从ARGC获得.第一个元素下标为0,最后一个下标是ARGC-1.

$ echo a | awk '{for (x in ARGV) print x,":",ARGV[x]} END{print ARGC}' m=1   #打印出命令行参数所有值ARGV,和个数ARGC

ENVIRON:环境变量数组.每个元素是当前环境变量的值,其下标是环境变量的名字.

$ echo a | awk '{for (x in ENVIRON) print x,":",ENVIRON[x]}' #打印当前系统环境变量值

修改ENVIRON数组中的元素不会修改环境变量.下例执行后HOSTNAME在shell环境中的值不会改变.

ENVIRON[HOSTNAME]="SPURS"

猜你喜欢

转载自xiangzi21.iteye.com/blog/865778
今日推荐