If I got your intention right, I don't think you need the shell loop. Instead, give awk the name(s) of the file(s) to read on the command line. We can pass the keyword to look for with -v, it sets an awk variable from the command line.
So, for every line that contains 'age', this would print the field number(s) where it appears:
$ cat schemas.txt
People height weight age race occupation
age is first on this line
$ keyword=age
$ awk -vk="$keyword" '{ for (i = 1 ; i <= NF ; i++) if($i == k) print i }' schemas.txt
4
1
Of course the fixed keyword is just for an example, you can use awk -vk="$3", and skip the extra variable.
In general, that looks like it could be useful to print the line numbers too, you could use print NR, i to do that.
Here,
schemas="schemas.txt"
for i in ${schemas[@]};
do
awk '{for(i=1;i<=NF;i++)if($i=="$3")print i}'
done
schemas only contains schemas.txt, so that's what the shell variable i gets set to in the loop. It's unused within the loop, though, so the loop doesn't really do much. The i in the awk script is independent from the shell i.
awk would seem to hang here, since by default it reads from stdin. Also, "$3" isn't expanded by the shell within the single quotes, so awk would look for a field literally containing $3.
The loop would make more sense with multiple files:
files=(file1.txt file2.txt)
for file in "${files[@]}"; do
awk '{...}' "$file"
done
but even then you might as well pass all the files to awk in one go:
awk '{...}' "${files[@]}"