如何将变量切片为数组索引?

时间:2016-11-28 14:24:07

标签: arrays awk gawk

存在这个典型问题:给定一个值列表,检查它们是否存在于数组中。

awk中,技巧val in array确实很有效。因此,典型的想法是将所有数据存储在一个数组中,然后继续进行检查。例如,这将打印阵列中存在第一列值的所有行:

awk 'BEGIN {<<initialize the array>>} $1 in array_var' file

但是,正在初始化数组需要一些时间,因为val in array检查索引val是否在array中,而我们通常存储在array中的是一组价值观。

当从命令行提供值时,这变得更加相关,其中那些是我们想要包括为数组索引的元素。例如,在这个基本示例中(基于recent answer of mine,它引发了我的好奇心):

$ cat file
hello 23
bye 45
adieu 99
$ awk -v values="hello adieu" 'BEGIN {split(values,v); for (i in v) names[v[i]]} $1 in names' file
hello 23
adieu 99
  • split(values,v)将变量values切成数组v[1]="hello"; v[2]="adieu"
  • for (i in v) names[v[i]]初始化另一个数组names[]names["hello"]names["adieu"]为空值。这样,我们就可以了
  • $1 in names检查第一列是否为names[]中的任何索引。

如您所见,我们切入一个临时变量v,以便稍后初始化最终有用的变量names[]

有没有更快的方法来初始化数组的索引而不是设置一个,然后使用它的值作为权威的索引?

2 个答案:

答案 0 :(得分:3)

不,这是最快的(由于哈希查找)和最强大的(由于字符串比较)方式来做你想要的。

此:

BEGIN{split(values,v); for (i in v) names[v[i]]}

在启动时发生一次,并且在此时间内几乎没有时间:

$1 in array_var

对于每一行输入都会发生一次(因此需要具有最佳性能的位置)是散列查找,因此是将字符串值与一组字符串进行比较的最快方法。

答案 1 :(得分:2)

不是数组解决方案,但一个技巧是使用模式匹配。要消除部分匹配,请使用分隔符包装搜索和数组值。对于你的例子,

\en\