Pass argument to awk inside do loop Pass argument to awk inside do loop shell shell

Pass argument to awk inside do loop


In your shell script, the first argument to the shellscript is available as $1. You can assign that value to an awk variable as follows:

find . -name 'test_score_*.txt' -type f -exec awk -v a="$1" -F'\t' '$2 < a' {} +

Discussion

  • Your print0/while read loop is very good. The -exec option offered by find, however, makes it possible to run the same command without any explicit looping.

  • The command {if ($2 < -7.5) print $0} can optionally be simplified to just the condition $2 < -7.5. This is because the default action for a condition is print $0.

  • Note that the references $1 and $2 are entirely unrelated to each other. Because $1 is in double-quotes, the shell substitutes in for it before the awk command starts to run. The shell interprets $1 to mean the first argument to the script. Because $2 appears in single quotes, the shell leaves it alone and it is interpreted by awk.  Awk interprets it to mean the second field of its current record.


Your first example:

awk '{FS = "\t" ; if ($2 < -7.5) print $0}' "$x"

only works by a happy coincidence that setting FS actually makes no difference for your particular case. Otherwise it would fail for the first line of the input file since you're not setting FS until AFTER the first line is read and has been split into fields. You meant this:

awk 'BEGIN{FS = "\t"} {if ($2 < -7.5) print $0}' "$x"

which can be written more idiomatically as just:

awk -F'\t' '$2 < -7.5' "$x"

For the second case you're just not passing in the argument, as you already realised. All you need to do is:

awk -F'\t' -v max="$1" '$2 < max' "$x"

See http://cfajohnson.com/shell/cus-faq-2.html#Q24.