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 correc
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.
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]
}
}'
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
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
.)