Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use array variable in awk?

Tags:

bash

awk

A=(aaa bbb ccc)    
cat abc.txt | awk '{ print $1, ${A[$1]} }'

I want to index an array element based on the $1, but the code above is not correct in awk syntax. Could someone help?

like image 726
Dagang Avatar asked Mar 23 '11 02:03

Dagang


4 Answers

You can't index a bash array using a value generated inside awk, even if you weren't using single quotes (thereby preventing bash from doing any substitution). You could pass the array in, though.

A=(aaa bbb ccc)
awk -v a="${A[*]}" 'BEGIN {split(a, A, / /)}
                     {print $1, A[$1] }' <abc.txt

Because of the split function inside awk, the elements of A may not contain spaces or newlines. If you need to do anything more interesting, set the array inside of awk.

awk 'BEGIN {a[1] = "foo bar"  # sadly, there is no way to set an array all
            a[2] = "baz"    } #   at once without abusing split() as above
           {print $1, a[$1] }' <abc.txt

(Clarification: bash substitutes variables before invoking the program whose argument you're substituting, so by the time you have $1 in awk it's far too late to ask bash to use it to substitute a particular element of A.)

like image 197
geekosaur Avatar answered Oct 06 '22 02:10

geekosaur


You can also print each element of the array on separate line with printf and pipe it to awk. This code will simply print bash array (bash_arr) from awk:

bash_arr=( 1 2 3 4 5 )
printf '%s\n' "${bash_arr[@]}" | 
    awk '    { awk_arr[NR] = $0 }
         END {
             for (key in awk_arr) {
                 print awk_arr[key]
             }
         }'
like image 42
yaeuge Avatar answered Oct 06 '22 02:10

yaeuge


If you are going to be hard-coding the A array, you can just initialize it in awk

awk 'BEGIN{A[0]="aaa";A[1]="bbb"}{ print $1, A[$1] }' abc.txt
like image 40
kurumi Avatar answered Oct 06 '22 01:10

kurumi


Your awk program within single quotes cannot see the shell environment variable A. In general, you can get a little shell substitution to work if you use double quotes instead of single quotes, but that is done by the shell, before awk is invoked. Overall, it is heavy sledding to try to combine shell and awk this way. If possible, I would take kurumi's approach of using an awk array.

Single quotes: an impenetrable veil. Double quotes: generally too much travail. So pick your poison: shell or awk. Otherwise: your code may balk.

like image 37
George Freeman Avatar answered Oct 06 '22 02:10

George Freeman