7

我希望能够将数组变量传递给awk. 我的意思不是 shell 数组,而是原生数组awk。我知道我可以像这样传递标量变量:

awk -vfoo="1" 'NR==foo' file

我可以使用相同的机制来定义awk数组吗?就像是:

$  awk -v"foo[0]=1" 'NR==foo' file
awk: fatal: `foo[0]' is not a legal variable name

我已经尝试了上述的一些变体,但它们都不能在我的 Debian 上的 GNU awk 4.1.1 上运行。那么,是否有任何版本的awk(gawk或其他任何东西) 可以接受来自交换机mawk的数组?-v

我知道我可以解决这个问题并且可以很容易地想到这样做的方法,我只是想知道是否有任何awk实现本身支持这种功能。

4

4 回答 4

5

您可以使用 mawk 或 gawk 中的 split() 函数来拆分“-v”值的输入(这里是 gawk 手册页):

split(s, a [, r [, seps] ])

将字符串 s 拆分为数组 a 和正则表达式 r 上的分隔符数组 seps,并返回字段数。*

这里有一个例子,我将值“ARRAYVAR”,一个逗号分隔的值列表,这是我的数组,用“-v”传递给 awk 程序,然后使用 split() 将其拆分为内部变量数组“arrayval”函数,然后打印数组的第三个值:

echo 0 | gawk -v ARRAYVAR="a,b,c,d,e,f" '{ split(ARRAYVAR,arrayval,","); print(arrayval[3]) }'
c

似乎工作:)

于 2015-10-13T21:50:03.213 回答
1

从定义上看,这似乎是不可能的。

man awk我们有:

-v 变量=val

--assign var=val

在程序开始执行之前,将值 val 赋给变量 var。此类变量值可用于 AWK 程序的 BEGIN 规则。

然后我们读到在程序中使用变量

变量的名称必须是字母、数字或下划线的序列,并且不能以数字开头。

awk 中的变量可以分配数值或字符串值。

因此,-v定义实现的方式使得将数组作为变量提供是不可能的,因为任何类型的字符使用=[不允许作为-v变量传递的一部分。两者都是必需的,因为数组awk只是关联的。

于 2015-10-13T15:10:24.417 回答
0

不幸的是,这是不可能的。但是,您可以使用一些巧妙的方法将 bash 数组转换为 awk 数组。

我最近想通过将 bash 数组传递给 awk 来使用它进行过滤来做到这一点,所以这就是我所做的:

$ arr=( hello world this is bash array )
$ echo -e 'this\nmight\nnot\nshow\nup' | awk 'BEGIN {
  for (i = 1; i < ARGC; i++) {
      my_filter[ARGV[i]]=1
      ARGV[i]="" # unset ARGV[i] otherwise awk might try to read it as a file
  }
} !my_filter[$0]' "${arr[@]}"

输出:

might
not
show
up
于 2021-04-11T09:28:25.410 回答
-1

对于关联数组,您可以将其作为键值对字符串传递,然后在 BEGIN 部​​分重新格式化。

$ echo | awk -v m="a,b;c,d" '
BEGIN {
  split(m,M,";")
  for (i in M) {
    split(M[i],MM,",")
    MA[MM[1]]=MM[2]
  }
}
{
  for (a in MA) {
    printf("MA[%s]=%s\n",a, MA[a])
  }
}'

输出:

MA[a]=b
MA[c]=d
于 2022-01-05T09:25:58.377 回答