Arguments to 'awk' scripts
Suppose we wished to write a shell script called
price , which would take one argument, representing a
vegetable name, and interrogate the file vegetables as
before to display the total price paid for that vegetable. One
solution would be to get Awk to evaluate the total cost for all
vegetables, and then use Grep to filter out the single line of
output from awk :
awk '{ printf "%s %.2f\n", $1, $2*$3 }' vegetables | grep $1
Note that in grep $1 , the $1 refers to
the first argument of the shell script.
This is a perfectly acceptable solution. Another would be to use
a pattern for awk so that only that single line would
be processed by awk . But here is a problem - we cannot
use the following:
awk '/$1/ { printf "%s %.2f\n", $1, $2*$3 }' vegetables
The pattern /$1/ is an ERE pattern. The character
$ in an ERE matches the end of a string, and since
each record Awk processes is a line, $ matches the end
of an input line. The ERE $1 , and thus the
awk pattern /$1/ , will match all lines
containing the digit 1 as the character after the end
of that line. This an impossible pattern, so it will not be matched
by any line. Try it - you should expect not to get any output. The
point to remember is that the $1 has nothing to do
with the $1 that would represent the first argument to
a shell script.
There is, fortunately, a way around this problem. When invoking
awk you can preset Awk variables by specifying their
initial value on the command line. So, we could assign an Awk
variable called veg (say), which would start off with
the value that was the first argument to the script:
awk '{ if (veg == $1)
printf "%s %.2f\n", $1, $2*$3 }' veg=$1 vegetables
By placing veg=$1 immediately after the Awk script,
it will set the value of veg to $1 - the
first argument to the shell script - as soon as awk
starts up. Another method would be to use veg as part
of a pattern:
awk ' veg == $1
{ printf "%s %.2f\n", $1, $2*$3 }' veg=$1 vegetables
Worked example
Write a shell script to take a single argument, representing a
cost in pence, and print out the names of all vegetables listed in
file vegetables that cost more than that number of
pence per kilo.
Solution: Use awk , but pass a
variable cost to it that is set to the first argument
of the shell script.
# First, check the shell script has one argument
if [ $# -ne 1 ]
then echo "One argument needed"
exit 1
fi
# Now fire awk ...
awk '{ if ($2 * 100 >= cost)
printf "%s\n", $1 }' cost=$1 vegetables
# Exit cleanly
exit 0
|