5

I'm trying to abuse asort() (just because) to copy an array src to array dest, no problem there:

$ awk 'BEGIN {
    split("first;second;third",src,";") # make src array for testing
    asort(src, dest, "@ind_num_asc")    # copy array to dest
    for(i in dest) 
        print i, src[i], dest[i]        # output
}'
1 first first
2 second second
3 third third

But is there a way use a multidimensional array as the dest array? Something like:

asort(src, dest[src[1]], "@ind_num_asc") # or dest[src[1]][]

(former produces second argument not an array, latter syntax error In reality the first argument of split is $0 and I'm trying to group records.)

Of course I could use for loop but my brain is stuck on testing this solution.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
James Brown
  • 36,089
  • 7
  • 43
  • 59
  • Funny thing is that if you define the array beforehand with `dest["first"][1]=""` it then gives a "fatal: attempt to use array `dest["first"]' in a scalar context" error. Interesting to read the last part of [GNU awk on array of arrays](https://www.gnu.org/software/gawk/manual/html_node/Arrays-of-Arrays.html): _Recall that a reference to an uninitialized array element yields a value of "", the null string. This has one important implication when you intend to use a subarray as an argument to a function_. – fedorqui Sep 02 '16 at 09:40
  • Yeah, really not not consistent regarding that example and `asort`. I played around with `split`ting to `dest["tmp"]` also but the `asort` is still not very willing. – James Brown Sep 02 '16 at 10:18
  • The `asort()` and `split()` functionalities are complete consistent and behave exactly [as document](https://www.gnu.org/software/gawk/manual/gawk.html#Arrays-of-Arrays), not sure where the misunderstanding/confusion is coming from. – Ed Morton Sep 02 '16 at 19:17

1 Answers1

4

You just need to create an array under dest[src[1]] first so gawk knows that dest[src[1]] is an array of arrays rather than the default array of strings:

$ cat tst.awk
BEGIN {
    split("first;second;third",src,/;/) # make src array for testing

    asort(src, dest1d)              # copy array to dest1d
    for(i in dest1d)
        print i, src[i], dest1d[i]      # output
    print ""

    dest2d[src[1]][1]
    asort(src, dest2d[src[1]])          # copy array to dest2d
    for(i in dest2d)
        for (j in dest2d[i])
            print i, j, dest2d[i][j]    # output
}

$ gawk -f tst.awk
1 first first
2 second second
3 third third

first 1 first
first 2 second
first 3 third

It doesn't matter what index you give that initial sub-array as it'll get deleted by the asort(). See the very last example under https://www.gnu.org/software/gawk/manual/gawk.html#Arrays-of-Arrays:

Recall that a reference to an uninitialized array element yields a value of "", the null string. This has one important implication when you intend to use a subarray as an argument to a function, as illustrated by the following example:

$ gawk 'BEGIN { split("a b c d", b[1]); print b[1][1] }'
error→ gawk: cmd. line:1: fatal: split: second argument is not an array

The way to work around this is to first force b[1] to be an array by creating an arbitrary index:

$ gawk 'BEGIN { b[1][1] = ""; split("a b c d", b[1]); print b[1][1] }'
-| a
fedorqui
  • 275,237
  • 103
  • 548
  • 598
Ed Morton
  • 188,023
  • 17
  • 78
  • 185