使用 -v 選項將引數傳遞給程式

選項 -v 後跟表單 variable = value 的賦值可用於將引數傳遞給 awk 程式。這是通過圖示的處罰下面的程式,其任務是寫計數時間了句“我不會在課堂上講話。”在標準輸出。以下示例使用值 100,這在教師中非常流行:

awk -v count=100 'BEGIN {
  for(i = 1; i <= count; ++i) {
    print("I shall not talk in class.")
  }
  exit
}'

重複使用 -v 標誌可以傳遞多個引數:

awk -v count=100 -v "sentence=I shall not talk in class." 'BEGIN {
  for(i = 1; i <= count; ++i) {
    print(sentence)
  }
  exit
}'

沒有對陣列或列表引數的內建支援,這些必須手動處理。傳遞 list 引數的經典方法是使用分隔符連線列表,流行的選擇是:|,。然後 split 函式允許將列表恢復為 awk 陣列:

awk -v 'serialised_list=a:b:c:d:e:f' 'BEGIN {
  list_sz = split(serialised_list, list, ":")
  for(i = 1; i <= list_sz; ++i) {
    printf("list: %d: %s\n", i, list[i])
  }
  exit
}'

這個 awk 程式的輸出是

list: 1: a
list: 2: b
list: 3: c
list: 4: d
list: 5: e
list: 6: f

有時將列表項恢復為 awk 陣列的鍵更方便,因為這樣可以輕鬆進行成員身份驗證。例如,以下程式列印第一個單詞不屬於固定異常列表的每一行:

awk -v 'serialised_exception_list=apple:pear:cherry' 'BEGIN {
  _list_sz = split(serialised_exception_list, _list, ":")
  for(i = 1; i <= _list_sz; ++i) {
    exception[_list[i]]
  }
}

! ($1 in exception) { print }' <<EOF
apple Apples are yummy, I like them.
pineapple Do you like pineapple?
EOF

這個程式的輸出是

pineapple Do you like pineapple?

作為最後一個例子,我們展示瞭如何將懲罰程式包裝到 shell 指令碼中,因為這說明了 shell 指令碼如何將引數傳遞給輔助 awk 指令碼:

#!/bin/sh

usage()
{
   cat <<EOF
Usage: punishment [-c COUNT][-s SENTENCE]
 Prepare your punishments for you
EOF
}

punishment_count='100'
punishment_sentence='I shall not talk in class.'
while getopts "c:hs:" OPTION; do
  case "${OPTION}" in
    c) punishment_count="${OPTARG}";;
    s) punishment_sentence="${OPTARG}";;
    h) usage; exit 0;;
    *) usage; exit 64;;
  esac
done

awk -v "count=${punishment_count}" -v "sentence=${punishment_sentence}" 'BEGIN {
  for(i = 1; i <= count; ++i) {
    print(sentence)
  }
  exit
}'