天天看點

awk中的數組

awk中的數組,原文參見[1]

因為awk中數組的下标可以是數字和字母,數組的下标通常被稱為關鍵字(key)。值和關鍵字都存儲在内部的一張針對key/value應用hash的表格 裡。由于hash不是順序存儲,是以在顯示數組内容時會發現,它們并不是按照你預料的順序顯示出來的。數組和變量一樣,都是在使用時自動建立的,awk也同樣會自動判斷其存儲的是數字還是字元串。

例1:

/> awk 'BEGIN {for(i = 0; i < ARGC; i++) printf("argv[%d] is %s.\n",i,ARGV[i]); printf("The number of arguments, ARGC=%d\n",ARGC)}' testfile "Peter Pan" 12

argv[0] is awk.

argv[1] is testfile.

argv[2] is Peter Pan.

argv[3] is 12.

The number of arguments, ARGC=4

從輸出結果可以看出,指令行參數數組ARGV是以0作為起始下标的,指令行的第一個參數為指令本身(awk),這個使用方式和C語句main函數完全一緻。

例2:

/> awk 'BEGIN{name=ARGV[2]; print "ARGV[2] is " ARGV[2]}; $1 ~ name{print $0}' testfile2 "bob"   

ARGV[2] is bob

bob

awk: (FILENAME=testfile2 FNR=9) fatal: cannot open file `bob' for reading (No such file or directory)

先解釋一下以上指令的含義,name變量被指派為指令行的第三個參數,即bob,之後再在輸入檔案中找到比對該變量值的記錄,并列印出該記錄。

在輸出的第二行報出了awk的處理錯誤資訊,這主要是因為awk将bob視為輸入檔案來處理了,然而事實上這個檔案并不存在,下面我們需要做進一步的處理來修正這個問題。

例3:

/> awk 'BEGIN{name=ARGV[2]; print "ARGV[2] is " ARGV[2]; delete ARGV[2]}; $1 ~ name{print $0}' testfile2 "bob"   

從輸出結果中我們可以看到我們得到了我們想要的結果。需要注意的是delete函數的調用必要要在BEGIN子產品中完成,因為這時awk還沒有開始讀取指令行參數中指定的檔案。

例4:

awk中還提供了一種special for的循環,見如下聲明:

for (item in arrayname)

{

print arrayname[item]

}

/> awk '{count[$1]++}; END{for(name in count) printf "%-5s%d\n",name, count[name]}' testfile2

mary 4

tom 2

alex 1

bob 1

sean 1

例5:

/> awk '{count[$1]++}; END{for(name in count) {if (count[name] == 1) delete count[name];} for (name in count) print name}' testfile2

上例中的主要技巧來自END子產品,先是變量count數組,如果數組中某個元素的值等于1,則删除該元素,這樣等同于删除隻出現一次的名字。最後用special for循環列印出數組中仍然存在的元素下标名稱。

原文:

http://www.cnblogs.com/mchina/archive/2012/06/30/2571317.html