As others have said, awk provides no functionality like this out of the box. Your "hackish" workaround may work for some datasets, but not others. Consider that you might add the same array value twice, and want it represented twice within the array.
$ echo 3 | awk 'BEGIN{ a[1]=5; a[2]=12; a[3]=2 }
> { a[$1] = $1 }
> END {print length(a) " - " a[3]}'
3 - 3
The best solution may be informed by the data are in the array, but here are some thoughts.
First off, if you are certain that your index will always be numeric, will always start at 1, and that you will never delete array elements, then triplee's suggestion of A[length(A)+1]="value"
may work for you. But if you do delete an element, then your next write may overwrite your last element.
If your index does not matter, and you're not worried about wasting space with long keys, you could use a random number that's long enough to reduce the likelihood of collisions. A quick & dirty option might be:
srand()
a[rand() rand() rand()]="value"
Remember to use srand()
for better randomization, and don't trust rand()
to produce actual random numbers. This is a less than perfect solution in a number of ways, but it has the advantage of being a single line of code.
If your keys are numeric but possibly sparse, as in the example that would break tripleee's solution, you can add a small search to your push function:
function push (a, v, n) {
n=length(a)+1
while (n in a) n++
a[n]=v
}
The while loop insures that you'll assign an unused index. This function is also compatible with arrays that use non-numeric indices -- it assigns keys that are numeric, but it doesn't care what's already there.
Note that awk does not guarantee the order of elements within an array, so the idea that you will "push an item onto the end of the array" is wrong. You'll add this element to the array, but there's no guarantee it's appear last when you step through with a for
loop.
$ 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