[Shell] awk 陣列(1)

tolilong發表於2016-04-27
在論壇上看到的問題,將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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章