使用 -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
}'