[Shell] awk 数组(1)

在论坛上看到的问题,将tt6中的第三列的内容替换为tt5中的内容,关联列是tt5的第一列和tt6的第六列
[/tmp/test]# cat tt5    
Z82004A        70
Z82004B        70
Zxxxb        70
Z7D009B        70
ZKH919C        40
ZKH919B        40
ZKH919A        40
[/tmp/test]# cat tt6
GSA8H2        Z82004        60        11        44        Z82004A        109
GSA8H2        Z82004        60        92        99        Z82004B        109
GSA8H2        Z7D009        60        42        46        Z7D009A        109
GSA8H2        Z7D009        60        6        47        Z7D009B        109
GST6H1        ZKH919        60        44        22        ZKH919C        109
GST6H1        ZKH919        60        33        49        ZKH919B        109
GST6H1        ZKH919        60        46        50        ZKH919A        109


[/tmp/test]# awk 'FNR==NR{a[$1]=$2;next}{if(a[$6]){sub($3,a[$6])}}1' tt5 tt6
GSA8H2        Z82004        70        11        44        Z82004A        109
GSA8H2        Z82004        70        92        99        Z82004B        109
GSA8H2        Z7D009        60        42        46        Z7D009A        109
GSA8H2        Z7D009        70        6        47        Z7D009B        109
GST6H1        ZKH919        40        44        22        ZKH919C        109
GST6H1        ZKH919        40        33        49        ZKH919B        109
GST6H1        ZKH919        40        46        50        ZKH919A        109


awk 'FNR==NR{a[$1]=$2;next}{if(a[$6]){sub($3,a[$6])}}1' tt5 tt6
可以解释为:
FNR=NR成立的时候执行{a[$1]=$2;next},即以tt5的第一列为下坐标值,第二列为数组值,next为循环使用.
FNR=NR不成立的时候执行{if(a[$6]){sub($3,a[$6])}}, a[$6]表示数组中,$6(tt6第六列)为下坐标时有值是否成立,则利用sub替换tt6第三列$3的值为a[$6]


数组相关信息
1.一维数组
[/]# awk 'BEGIN{a[1]="1";a[2]="4";a[3]="9";a[4]="16";a["f"]="25";a["h"]="36";print a[1],a[3],a["f"],a["h"]}'
1 9 25 36


[/]# awk 'BEGIN{for(i=1;i<=10;i++){a[i]=i*2-1} for(i in a){print i"="a[i]}}'
2=3
3=5
4=7
5=9
6=11
7=13
8=15
9=17
10=19
1=1


2.二维数组
awk 多维数组在本质上是一维数组,因awk在存储上并不支持多维数组,awk提供了逻辑上模拟二维数组的访问方式。例如,array[2,3] = 1这样的访问是允许的。
awk使用一个特殊的字符串SUBSEP (\034)作为分割字段,在上面的例子 array[2,3] = 1 中,关联数组array存储的键值实际上是2\0343,2和3分别为下标(2,3),\034为SUBSEP分隔符


类似一维数组的成员测试,多维数组可以使用 if ( (i,j) in array) 语法,但是下标必须放置在圆括号中。
类似一维数组的循环访问,多维数组使用 for ( item in array ) 语法遍历数组。
与一维数组不同的是,多维数组必须使用split()函数来访问单独的下标分量,格式: split ( item, subscr, SUBSEP), 
例如: split (item, b, SUBSEP); 后,b[1]为下标“2”, b[2]为下标“3”

[/]# awk 'BEGIN{for(i=1;i<=3;i++){for(j=1;j<=3;j++){a[i,j]=i * j ; print i"*"j"="a[i,j]}}}' 
1*1=1
1*2=2
1*3=3
2*1=2
2*2=4
2*3=6
3*1=3
3*2=6
3*3=9


[/]# awk 'BEGIN{for(i=1;i<=3;i++){for(j=1;j<=3;j++){a[i,j]=i*j; print i"*"j"="a[i,j]}}
> print "\n"
> for(i in a){split(i,b,SUBSEP);print b[1]"*"b[2]" = "a[i]}}'
1*1=1
1*2=2
1*3=3
2*1=2
2*2=4
2*3=6
3*1=3
3*2=6
3*3=9


1*1 = 1
1*2 = 2
1*3 = 3
2*1 = 2
2*2 = 4
2*3 = 6
3*1 = 3
3*2 = 6
3*3 = 9


3.数组长度
[/]# awk 'BEGIN{str="This is a new thing";len=split(str,a," ");print len  
> print "\n"
> for(i in a){print i" = " a[i]}}'
5


2 = is
3 = a
4 = new
5 = thing
1 = This


4.数组排序
[/]# awk 'BEGIN{str="This is a new thing";len=split(str,a," ");print len;print "\n";for(i in a){print i"="a[i]};print "\n"
> for(i=1;i<=len;i++){print i"="a[i]}}'
5


2=is
3=a
4=new
5=thing
1=This


1=This
2=is
3=a
4=new
5=thing



5. 循环if,while,do while,for
[/]# awk 'BEGIN{tt=60;if(tt>=80){print "excellent"}else if(tt>=60){print "good"}else{print "bad"}}'
good

[/]# awk 'BEGIN{for(i=1;i<=4;i++){print i" power= "i*i}}'
1 power= 1
2 power= 4
3 power= 9
4 power= 16

[/]# awk 'BEGIN{tt=20;while(i<=tt){sum+=i;i++} print "sum:"sum;print "\n"
> do{sum+=i;i++}while(i<=tt);print "sum:"sum}'
sum:210

sum:231

[/]# awk 'BEGIN{for(x=0;x<=20;x++){if(x==5)continue; printf "%d",x} print ""}'                   #这里面的continue表示 x==5的时候,不执行接下来的statement,直接跳到x==6
0123467891011121314151617181920

[/]# awk 'BEGIN{x=0;while(x<=20){if(x==5) continue;printf"%d ",x;x++} print ""}'                #x==5的时候,会跳过x++,所以只会输出0 1 2 3 4
0 1 2 3 4

[/tmp/test]# awk '{for(i=1;i<=4;i++){if(i==3) next;print $0}}' ff1        #i==3的时候,接下来的statement不执行,直接读取一个record.


break 当 break 语句用于 while 或 for 语句时,导致退出程序循环。
continue 当 continue 语句用于 while 或 for 语句时,使程序循环移动到下一个迭代。
next 能能够导致读入下一个输入行,并返回到脚本的顶部。这可以避免对当前输入行执行其他的操作过程。
exit 语句使主输入循环退出并将控制转移到END,如果END存在的话。如果没有定义END规则,或在END中应用exit语句,则终止脚本的执行。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/24237320/viewspace-2089421/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/24237320/viewspace-2089421/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值