我意识到 awk 具有关联数组,但我想知道是否有与此等效的 awk:
http://php.net/manual/en/function.array-push.php
显而易见的解决方法就是说:
array[$new_element] = $new_element
然而,这似乎比它需要的可读性更差,更骇人听闻。
我意识到 awk 具有关联数组,但我想知道是否有与此等效的 awk:
http://php.net/manual/en/function.array-push.php
显而易见的解决方法就是说:
array[$new_element] = $new_element
然而,这似乎比它需要的可读性更差,更骇人听闻。
我认为 awk 中不会立即提供数组长度(至少在我摆弄的版本中不会)。但是您可以简单地保持长度,然后执行以下操作:
array[arraylen++] = $0;
然后通过相同的整数值访问它的元素:
for ( i = 0; i < arraylen; i++ )
print array[i];
您可以在gawk
其中找到数组的长度,length(var)
因此编写自己的函数并不难。
function push(A,B) { A[length(A)+1] = B }
不过请注意这个讨论:http: //objectmix.com/awk/361598-gawk-length-array-question.html——我现在可以访问的所有地方都有 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
正如其他人所说,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
最好的解决方案可能是数组中的数据,但这里有一些想法。
首先,如果您确定您的索引将始终为数字,始终从 1 开始,并且您永远不会删除数组元素,那么 Triplee 的建议A[length(A)+1]="value"
可能对您有用。但是,如果您确实删除了一个元素,那么您的下一次写入可能会覆盖您的最后一个元素。
如果您的索引无关紧要,并且您不担心长键会浪费空间,则可以使用足够长的随机数来减少冲突的可能性。一个快速而肮脏的选择可能是:
srand()
a[rand() rand() rand()]="value"
记住使用srand()
更好的随机化,不要相信rand()
产生实际的随机数。从很多方面来看,这并不是一个完美的解决方案,但它的优点是只需一行代码。
如果您的键是数字但可能是 sparse,例如会破坏三元组解决方案的示例,您可以在 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