Main index

Introducing UNIX and Linux


Awk

Overview
What is 'awk'?
Invoking 'awk'
Naming the fields
Formatted output
      Operators used by Awk
Patterns
Variables
      Accessing Values
      Special variables
Arguments to 'awk' scripts
Arrays
Field and record separators
Functions
      List of Awk functions
Summary
Exercises

Functions

Just as bc and expr have functions defined that you can use with them (such as exp), so does awk. We use here just some of the available Awk functions.

Worked example

Write a script to 'roll a die'. Each time a line of input is entered, the script should display a number between 1 and 6 to mimic someone throwing a die.
Solution: Use awk. All the input should be discarded, but whenever a line is entered from standard input the function rand is called to generate a number between 0 and 1 (but not including 1). This is multiplied by 6 to get a number between 0 and 6 (but not including 6). Adding 1 to this produces a number between 1 and 7, and giving this as argument to int yields a whole number between 1 and 6 inclusive.

awk '{ printf "%d\n", int(rand()*6 + 1) }'

The trigonometric functions use radians, not degrees, and the number returned by rand might be 0, but will be strictly less than 1.

Worked example

Write a shell script to read the password file and display each user's name in capitals.
Solution: Use awk to pass the fifth field of its input to the function toupper, the result of which is then displayed.

awk ' BEGIN { FS=":" }
 { print toupper($5) }' < /etc/passwd

Where a function takes a string as argument, that string is not itself altered, so that if you passed $0 to one of those functions, $0 would stay the same, but the function would return a new string based on $0.

Worked example

A certain Birmingham electrical retail company offers free delivery of its products to customers living in the Birmingham area, defined as having addresses with postcode commencing B followed by at least one digit. Delivery outside this area is charged at a flat rate per delivery. It is company practice for the driver of its delivery van to collect that fee. The company stores part of its customer data in the following format:

invoice number,customer,road,town,postcode

For example,

6152,J. Smith,1 High St.,Birmingham,B99 9ZZ
6183,F. Bloggs,5 Long Ave.,Dudley,DY1 1AA

The company requires a document to instruct the delivery driver whom to visit and whom to collect a delivery fee from.
Solution: This is an exercise that could be accomplished using Sed, although it would be quite messy. Using Awk we can use function match to examine the postcode. The ERE that matches a Birmingham postcode is

^B[0-9]

namely a B at the start of the postcode followed by one digit. What follows the digit - if anything - does not concern us. The Awk script might be:

# Set the field separator to be a comma
BEGIN { FS="," }

# For each line, $5 is the postcode
# Check if it is a Birmingham one
{ if ( match($5, "^B[0-9]") > 0)
     fee = "no fee"
 else
     fee = "standard fee"
 # Print out message for driver
 printf "%s, %s, %s, %s: %s\n", $2, $3, $4, $5, fee
 }

Copyright © 2002 Mike Joy, Stephen Jarvis and Michael Luck