AWK 中陣列的特色

AWK程式中允許使用字串當做陣列的註標(index). 利用 這個特色十分有助於資料統計工作.(使用字串當註標的陣列稱為 Associative Array) 首先建立一個資料檔, 並取名為 reg.dat. 此為一學生註冊的 資料檔; 第一欄為學生姓名, 其後為該生所修課程. Mary O.S. Arch. Discrete Steve D.S. Algorithm Arch. Wang Discrete Graphics O.S. Lisa Graphics A.I. Lily Discrete Algorithm AWK中陣列的特性
  1. 使用字串當陣列的註標(index).
  2. 使用陣列前不須宣告陣列名稱及其大小. 例如 : 希望用陣列來記錄 reg.dat 中各門課程的修課人數. 這情況,有二項資訊必須儲存 : (a) 課程名稱, 如 : ``O.S.'',``Arch.''.. ,共有哪些課程事前 並不明確. (b)各課程的修課人數. 如 : 有幾個人修``O.S.'' 在AWK中只要用一個陣列就可同時記錄上列資訊. 其方法如下 : 使用一個陣列 Number[ ] :
    • 以課程名稱當 Number[ ] 的註標.
    • 以 Number[ ] 中不同註標所對映的元素代表修課人數.
    例如 : 有2個學生修 ``O.S.'', 則以 Number[``O.S.''] = 2 表之. 若修``O.S.''的人數增加一人,

    則 Number[``O.S.''] = Number[``O.S.''] + 1

    或 Number["O.S."]++ .

  3. 如何取出陣列中儲存的資訊 以 C 語言為例, 宣告 int Arr[100]; 之後, 若想得知 Arr[ ]中所 儲存的資料, 只須用一個迴圈, 如 : for(i=0; i<00; i++) printf("%d\n", Arr[i]); 即可. 上式中 : 陣列 Arr[ ] 的註標 : 0, 1, 2,..., 99 陣列 Arr[ ] 中各註標所對應的值 : Arr[0], Arr[1],...Arr[99] 但 AWK 中使用陣列並不須事先宣告. 以剛才使用的 Number[ ] 而言, 程式執行前, 並不知將來有哪些課程名稱可能被當成 Number[ ] 的 註標. AWK 提供了一個指令, 藉由該指令AWK會自動找尋陣列中使用過 的所有註標. 以 Number[ ] 為例, AWK將會找到 ``O.S.'', ``Arch.''",... 使用該指令時, 須指定所要找尋的陣列, 及一個變數. AWK會使用 該的變數來記錄從陣列中找到的每一個註標. 例如

for(course in Number){....}

指定用 course 來記錄 AWK 從Number[ ] 中所找到 的註標. AWK每找到一個註標時, 就用course記錄該註標之值且 執行{....}中之指令. 藉由這個方式便可取出陣列中儲存的資訊. (詳見下例) 範例 : 統計各科修課人數,並印出結果. 建立如下程式,並取名為 course.awk: { for( i=2; i

END{for(coursein Number)

printf("\%-10s %d\n", course, Number[course] ) } 執行下列命令 : awk -f course.awk reg.dat 執行結果如下 :
Discrete 3
D.S. 1
O.S. 2
Graphics 2
A.I. 1
Arch. 2
Algorithm 2
說 明 :
  1. 這程式包含二個Pattern { Actions }指令.
    Pattern Actions
    {for( i=2; i< NF; i++) Number[$i]++ }
    END { for( course in Number) printf("\%-10s \%d\n", course, Number[course] )}
  2. 第一個Pattern { Actions }指令中省略了Pattern 部分. 故隨著 每筆資料列的讀入其Actions部分將逐次無條件被執行. 以AWK讀入第一筆資料 `` Mary O.S. Arch. Discrete" 為例, 因為該筆資料 NF = 4(有4個欄位), 故該 Action 的for Loop中 i = 2,3,4.
    i$i 最初 Number[$i] Number[$i]++ 之後
    2``O.S.'' AWK default Number[``O.S'']=0 1
    3``Arch.'' AWK default Number[``Arch'']=0 1
    4``Discrete'' AWK default Number[``Discrete'']=0 1
  3. 第二個 Pattern { Actions }指令中 * { END}為AWK之保留字, 為{ Pattern}之一種. * { END}成立(其值為true)的條件是 :[0.3cm] ``AWK處理完所有資料, 即將離開程式時. 平常讀入資料列時, END並不成立, 故其後的Actions 並不被執行; 唯有當AWK讀完所有資料時, 該Actions才會被執行 ( 注意, 不管資料列有多少筆, END僅在最後才成立, 故該Actions僅被執行 一次.) { BEGIN} 與 { END} 有點類似, 是AWK中另一個保留的{Pattern}. 唯一不同的是 : ``以 { BEGIN 為 Pattern 的 Actions} 於程式一開始執行時, 被執行 一次.''
  4. NF 為AWK的內建變數, 用以表示AWK正處理的資料計列中, 所包含的欄位個數.
  5. AWK程式中若含有以 $ 開頭的自定變數, 都將以如下方式解釋 : 以 i= 2 為例, $i = $2 表第二個欄位資料. ( 實際上, $ 在 AWK 中 為一運算元(Operator), 用以取得欄位資料.)