Linux高階文字處理之gawk關聯陣列
Awk 的陣列,都是關聯陣列,即一個陣列包含多個”索引/值”的元素。 索引沒必要是一系列 連續的數位,實際上,它可以使字串或者數位,並且不需要指定陣列長度。
語法:
arrayname[string]=value
-
arrayname 是陣列名稱
-
string 是陣列索引
-
value 是為陣列元素賦的值
存取 awk 陣列的元素
如果要存取陣列中的某個特定元素,使用 arrayname[index] 即可返回該索引中的值。
範例1:
[root@localhost ~]# awk ' >BEGIN{ item[101]="HD Camcorder"; >item["102"]="Refrigerator"; >item[103]="MP3 Player"; >item["na"]="Young" >print item[101]; >print item["102"]; #注意帶引號不帶引號awk都視為字串來處理 >print item[103]; >print item["na"];}' #字串索引需要加雙引號 HD Camcorder Refrigerator MP3 Player Young
注意:
-
陣列索引沒有順序,甚至沒有從 0 或 1 開始.
-
陣列索引可以是字串,陣列的最後一個元素就是字串索引,即”na”
-
Awk 中在使用陣列前,不需要初始化甚至定義陣列,也不需要指定陣列的長度。
-
Awk 陣列的命名規範和 awk 變數命名規範相同。
以 awk 的角度來說,陣列的索引通常是字串,即是你使用陣列作為索引, awk 也會當 做字串來處理。下面的寫法是等價的:
Item[101]="HD Camcorder" Item["101"]="HD Camcorder"
一、參照陣列元素
如果試圖存取一個不存在的陣列元素, awk 會自動以存取時指定的索引建立該元素,並賦予 null 值。 為了避免這種情況,在使用前最後檢測元素是否存在。
使用 if 語句可以檢測元素是否存在,如果返回 true,說明改元素存在於陣列中。
if ( index in array-name )
範例2:一個簡單的參照陣列元素的例子
[root@localhost ~]# cat arr.awk BEGIN { x = item[55]; #在參照前沒有賦任何值,所以在參照是 awk 自動建立該元素並賦 null 值 if ( 55 in item ) print "Array index 55 contains",item[55]; item[101]="HD Camcorder"; if ( 101 in item ) print "Array index 101 contains",item[101]; if ( 1010 in item ) #不存在,因此檢查索引值時,返回 false,不會被列印 print "Array index 1010 contains",item[1010]; } [root@localhost ~]# awk -f arr.awk Array index 55 contains Array index 101 contains HD Camcorder
二、使用迴圈遍歷 awk 陣列
如果要存取陣列中的所有元素, 可以使用 for 的一個特殊用法來遍歷陣列的所有索引:
語法:
for ( var in arrayname ) actions
說明:
-
var 是變數名稱
-
in 是關鍵字
-
arrayname 是陣列名
-
actions 是一系列要執行的 awk 語句,如果有多條語句,必須包含在{ }中。 通過把索引值賦給變數 var,迴圈體可以把所有語句應用到陣列中所有的元素上。
範例1:將陣列中元素全部列印出來
[root@localhost ~]# cat arr-for.awk BEGIN { item[101]="HD Camcorder"; item[102]="Refrigerator"; item[103]="MP3 Player"; item[104]="Tennis Racket"; item[105]="Laser Printer"; item[1001]="Tennis Ball"; item[55]="Laptop"; item["no"]="Not Available"; for(x in item) #x 是變數名,用來存放陣列索引,無需制定條件,awk自行判斷 print item[x]; } [root@localhost ~]# awk -f arr-for.awk Not Available Laptop HD Camcorder Refrigerator MP3 Player Tennis Racket Laser Printer Tennis Ball
三、刪除陣列元素
如果要刪除特定的陣列元素,使用 delete 語句。一旦刪除了某個元素,就再也獲取不到它 的值了。
語法:
delete arrayname[index];
刪除陣列內所有元素:
for (var in array) delete array[var]
在 GAWK 中,可以使用單個 delete 命令來刪除陣列的所有元素:
Delete array
範例1:
[root@localhost ~]# awk ' >BEGIN{item[101]="HD Camcorder"; >item[102]="Refrigerator"; >item[103]="MP3 Player"; >delete item[101]; >print item[101];print item[102]; >for(x in item) delete item[x]; #使用for迴圈刪除全部陣列 >print item[102];print item[103];}' Refrigerator [root@localhost ~]#
範例2???
[root@localhost ~]# awk ' >BEGIN{item[1]="a"; >item[2]="b";item[3]="c"; >delete item; #使用delete直接加陣列名稱刪除全部陣列 >for(x in item) print item[x];}'
四、多維陣列
雖然 awk 只支援一維陣列,但可以使用一維陣列來模擬多維陣列。
範例1:
[root@localhost ~]# cat array-multi.awk BEGIN { item["1,1"]=10; item["1,2"]=20; item["2,1"]=30; item["2,2"]=40 for (x in item) print item[x] } [root@localhost ~]# awk -f array-multi.awk 30 20 40 10
說明:即使使用了”1,1”作為索引值,它也不是兩個索引,仍然是單個字串索引,值為”1,1”。所 以item[“1,1”]=10
,實際上是把 10 賦給一維陣列中索引”1,1”代表的值。
範例2:將雙引號去掉
[root@localhost ~]# cat array-multi2.awk BEGIN { item[1,1]=10; item[1,2]=20; item[2,1]=30; item[2,2]=40 for (x in item) print item[x] } [root@localhost ~]# awk -f array-multi2.awk 10 30 20 40
說明:上面的例子仍然可以執行,但是結果有所不同。在多維陣列中,如果沒有把下標用引號引住, awk 會使用”