我知道awk有关联数组,但我想知道是否有awk等效于这个功能:http://php.net/manual/en/function.array-push.php。显然的解决办法是只需说:
array[$new_element] = $new_element
然而,这似乎比必要的更不易读且更加 hackish。
array[$new_element] = $new_element
然而,这似乎比必要的更不易读且更加 hackish。
我认为在awk中数组长度不是立即可用的(至少在我使用的版本中是这样)。但你可以简单地维护一个长度,然后像这样做:
array[arraylen++] = $0;
然后通过相同的整数值访问它的元素:
for ( i = 0; i < arraylen; i++ )
print array[i];
length()
函数将返回数组中元素的数量,但由于数组是稀疏的,因此长度不一定是最后一个元素。 - Dennis Williamsonlength(arrayname)
的表示方式并不是只有 GAWK 才有。它在 2002 年被添加到了 One True Awk 中。可能是三年后,这个功能才出现在 gawk 中。 - ghotilength()
函数可以用于数组,从3.1版本开始,该版本于2001年6月发布。不确定我从哪里得到的2005年的想法,那个链接已经失效了。 - ghotigawk
中,你可以使用length(var)
来获取数组的长度,因此自己编写函数并不是很难。function push(A,B) { A[length(A)+1] = B }
注意这个讨论,不过 -- 我现在能够访问的所有地方都只有gawk 3.1.5,所以我无法对我的功能进行正确测试,呃。但是这是一个近似值。
vnix$ gawk '# BEGIN: make sure arr is an array
> BEGIN { delete arr[0] }
> { print "=" length(arr); arr[length(arr)+1] = $1;
> print length(arr), arr[length(arr)] }
> END { print "---";
> for (i=1; i<=length(arr); ++i) print i, arr[i] }' <<HERE
> fnord foo
> ick bar
> baz quux
> HERE
=0
1 fnord
=1
2 ick
=2
3 baz
---
1 fnord
2 ick
3 baz
A[length(A)+1]
” 这段代码片段不能保证避免冲突。它可以在某些情况下使用,例如您的示例中,只有按可预测的顺序向数组添加元素时。但是,如果您要删除数组元素,则会创建间隙,这会减少 length()
,同时保留最高数字。 - ghotirrdtool
可以在磁盘文件中使用持久存储执行类似操作。 - tripleee就像其他人所说的,awk没有提供类似此功能的内置功能。你的“hackish”解决方案可能适用于某些数据集,但对于其他数据集可能不起作用。请考虑您可能会将相同的数组值添加两次,并希望在数组中表示两次。
$ echo 3 | awk 'BEGIN{ a[1]=5; a[2]=12; a[3]=2 }
> { a[$1] = $1 }
> END {print length(a) " - " a[3]}'
3 - 3
A[length(A)+1]="value"
可能适合您。但是,如果您删除一个元素,那么下一个写入可能会覆盖您的最后一个元素。srand()
a[rand() rand() rand()]="value"
记得使用srand()
来获得更好的随机化效果,不要依赖rand()
来生成真正的随机数。这种方法在很多方面都不是完美的解决方案,但它有一个优点,那就是只需要一行代码。
如果你的键是数字但可能是稀疏的,就像在会破坏tripleee解决方案的示例中一样,你可以在push函数中添加一个小搜索功能:
function push (a, v, n) {
n=length(a)+1
while (n in a) n++
a[n]=v
}
while循环确保您将分配一个未使用的索引。此函数还与使用非数字索引的数组兼容 - 它会“分配”数值键,但不关心已经存在什么。
请注意,awk无法保证数组中元素的顺序,因此“将项目推入数组的末尾”的想法是错误的。您将向数组添加此元素,但无法保证它在使用for
循环遍历时最后出现。
$ cat a
#!/usr/bin/awk -f
function push (a, v, n) {
n=length(a)+1
while (n in a) n++
a[n]=v
}
{
push(a, $0)
}
END {
print "length=" length(a)
for(i in a) print i " - " a[i]
}
$ printf '3\nfour\ncinq\n' | ./a
length=3
2 - four
3 - cinq
1 - 3
length(A)+1
会导致 gawk 报错attempt to use scalar 'A' as an array
,进而需要 更多的解决方法。因此,在我看来,你的“hackish”解决方案是最具可移植性的。 - TheDudeAbides