Sams Teach Yourself Shell Programming in 24 Hours
(Publisher: Macmillan Computer Publishing)
Author(s): Sriranga Veeraraghavan
ISBN: 0672314819
Publication Date: 01/01/99

Previous Table of Contents Next


Taking Pattern-Specific Actions

Say that you want to highlight those fruits that cost more than a dollar by putting a * at the end of the line for those fruits. This means that you need to perform different actions depending on the pattern that was matched for the price.

Start with the following script:

#!/bin/sh
awk '
    / *\$[1-9][0-9]*\.[0-9][0-9] */ { print $1,$2,$3,"*"; }
    / *\$0\.[0-9][0-9] */ { print ; }
' fruit_prices.txt

Here you have two patterns: The first one looks for fruit priced higher than a dollar, and the second one looks for fruit priced lower than a dollar. When a fruit priced higher than a dollar is encountered, the three fields are output with a * at the end of the line. For all other fruit, the line is printed exactly as it was read. The output looks like the following:

Banana          $0.89           100
Peach           $0.79           65
Kiwi $1.50 22 *
Pineapple $1.29 35 *
Apple           $0.99           78

The main problem here is that the lines you wanted to flag with the * in are no longer formatted in the same manner as the other lines. You could solve this using printf, but a much nicer and simpler solution is to use the $0 field. The variable 0 is used by awk to store the entire input line as it was read. Change the script as follows:

#!/bin/sh
awk '
    / *\$[1-9][0-9]*\.[0-9][0-9] */ { print $0,"*"; }
    / *\$0\.[0-9][0-9] */ { print ; }
' fruit_prices.txt

This changes the output so that all the lines are formatted identically:

Banana          $0.89           100
Peach           $0.79           65
Kiwi            $1.50           22 *
Pineapple       $1.29           35 *
Apple           $0.99           78

Comparison Operators

Say that you have to flag all the fruit whose quantity is less than 75 for reorder by appending the string REORDER to the end of their line. In this case you have to check whether the third field, which holds the quantity, is less than or equal to 75.

To solve this problem, you need to use a comparison operator. In awk, comparison operators compare the values of numbers and strings. Their behavior is similar to operators found in the C language or the shell.

When you use a comparison operator, the syntax of an awk command changes to the following:

expression { actions; }

Here expression is constructed using one of the comparison operators given in Table 17.1

Table 17.1 Comparison Operators in awk

Operator Description

< Less than
> Greater than
<= Less than or equal to
>= Greater than or equal to
== Equal to
!= Not equal to
value ~ /pattern/ True if value matches pattern
value !~ /pattern/ True if value does not match pattern

You can solve your problem using the following script:

#!/bin/sh
awk '
    $3 <= 75 { printf "%s\t%s\n",$0,"REORDER" ; }
    $3 > 75 { print $0 ; }
' fruit_prices.txt

Here you check to see whether the third field contains a value less than or equal to 75. If it does, you print out the input line followed by the string REORDER. Next you check to see whether the third field contains a value greater than 75 and, if it does, you print the input line unchanged.

The output from this scripts looks like the following:

Fruit           Price/lbs       Quantity
Banana          $0.89           100
Peach           $0.79           65      REORDER
Kiwi            $1.50           22      REORDER
Pineapple       $1.29           35      REORDER
Apple           $0.99           78

Compound Expressions


Often you need to combine two or more expressions to check for a particular condition. When you combine two or more expressions, the result is called a compound expression.

Compound expressions are constructed by using either the && (and) or the || (or) compound operators. The syntax is

(expr1) && (expr2)
(expr2) || (expr2)

Here expr1 and expr2 are expressions constructed using the conditional operators given in Table 17.1. The parentheses surrounding expr1 and expr2 are required.

When the && operator is used, both expr1 and expr2 must be true for the compound expression to be true. When the || operator is used, the compound expression is true if either expr1 or expr2 is true.

As an example of using a compound expression, you can use the compound operators to obtain a list of all the fruit that cost more than a dollar and of which there are less than 75:

awk '
    ($2 ~ /^\$[1-9][0-9]*\.[0-9][0-9]$/) && ($3 < 75) {
        printf "%s\t%s\t%s\n",$0,"*","REORDER" ;
    }
' fruit_prices.txt ;

The output looks like the following

Kiwi            $1.50           22      *       REORDER
Pineapple       $1.29           35      *       REORDER
The Compound Expression Operators

You might hear the && operator called the and-and operator because it consists of two ampersands (and characters). Similarly, the || operator might be referred to as the or-or operator.

The next Command

Consider the following script:

#!/bin/sh
awk '
    $3 <= 75 { printf "%s\t%s\n",$0,"REORDER" ; }
    $3 > 75 { print $0 ; }
' fruit_prices.txt

Clearly it is performing more work than it needs to. For example, when the input line is

Kiwi            $1.50           22

the execution of the script is as follows:

1.  Check whether the value of the third column, 22, is less than 75. Because the value is less than 75, the script proceeds to step 2.
2.  Prints the input line followed by REORDER.
3.  Checks whether the value of the third column, 22, is greater than 75. Because the value is not greater than 75, the script reads the next line.


Previous Table of Contents Next