To start with,
Don't read lines with for. Use a
while+read loop, with the awk command supplied by a
process substitution (assuming bash, of course).
You shouldn't need to use
head either. You can import the variable directly into awk and use it to output the lines you want.
Code:
while read i; do
commands
done <( awk '( NR <= ln ) { print $2 }' "ln=$NR" "$GENE.bim" )
Edit: Similarly, you shouldn't need to use grep and awk (or grep and sed)
together in the sub-commands.
Code:
EA1=$( awk '( $0 ~ pat ) { print $3 }' 'pat=\\<'"$i"'\\>' "$FREQEA" )
The "
pat" variable in awk is treated as a regex to match, so that only lines containing the pattern will be printed.
\< and
\> are regex word boundary anchors, used to replicate the behavior of grep's "
-w" option. Unfortunately though, awkward quoting and backslashing is needed to properly pass them to awk. If you don't need the whole-word matching condition, you can simply use "
pat=$i".
Edit2: a slightly cleaner way to handle the regex, by adding the word boundries to the variable inside awk instead.
Code:
EA1=$( awk '{ pat="\\<" pat "\\>" } ; ( $0 ~ pat ) { print $3 }' "pat=$i" "$FREQEA" )
Speaking of which,
QUOTE ALL OF YOUR VARIABLE SUBSTITUTIONS. You should never leave the quotes off a variable expansion unless you explicitly want the resulting string to be word-split by the shell. This is a vitally important concept in scripting, so train yourself to do it correctly now. You can learn about the exceptions later.
Also, environment variables are generally all upper-case. So while not absolutely necessary, it's good practice to keep your own user variables in lower-case or mixed-case, to help differentiate them.