Chapter 11. Awk Conditional Statements and Loops

Awk supports conditional statements to control the flow of the program. Most of the Awk conditional statement syntax is similar to the ‘C’ programming language conditional statements. Awk supports the following three kinds of if statements.
  • Awk Simple If statement
  • Awk If-Else statement
  • Awk If-ElseIf-Ladder

69. Simple If Statement

The simple if statement tests a condition, and if the condition returns true, performs the corresponding action(s).

Single Action

Syntax:
if (conditional-expression) action
  • if is a keyword
  • conditional-expression represents the condition to be tested
  • action is an awk statement to perform

Multiple Actions

If more than one action needs to be performed when the condition is true, those actions should be enclosed in curly braces. The individual actions (awk statements) should be separated by new line or semicolon as shown below.
if (conditional-expression)
{
  action1;
  action2;
}
If the condition is true, all the actions enclosed in braces will be performed in the given order. After all the actions are performed, awk continues to execute the next statement. Print all the items with quantity <=5:
$ awk -F "," '{ if ($5 <= 5) print "Only",$5,"qty of",$2, "is available"; }' items.txt
Only 2 qty of Refrigerator is available
Only 5 qty of Laser Printer is available
You can also have multiple conditional operators in an if statement as shown below. This example prints all the items with price between 500 and 1000, and the total quantity <= 5
$ awk -F "," '{ if ( ($4 >= 500 && $4 <= 1000) && ($5 <= 5)) print "Only",$5,"qty of",$2,"is available";}' items.txt
Only 2 qty of Refrigerator is available

70. If Else Statement

In the awk "If Else" statement you can also provide list of actions to perform if the condition is false. In the following syntax, if the condition is true action1 will be performed, if the condition is false action 2 will be performed. Syntax:
if (conditional-expression)
  action1
else
  action2
Awk also has a conditional operator, the 'ternary operator' ( ?: ) which works like the equivalent one in C. Just like in the if-else statement, if the conditional-expression is true, action1 will be performed, and if the conditional-expression is false, action2 will be performed. Ternary Operator Syntax:
conditional-expression ? action1 : action2 ;
The following example displays the message "Buy More" when the total quantity is <= 5, and prints "Sell More" when the total quantity is not <=5.
$ cat if-else.awk
BEGIN { 
  FS=","; 
}
{
  if ( $5 <= 5 )
  print "Buy More: Order", $2, "immediately!"
  else 
  print "Sell More: Give discount on", $2,
  "immediately!"
}

$ awk -f if-else.awk items.txt
Sell More: Give discount on HD Camcorder immediately!
Buy More: Order Refrigerator immediately!
Sell More: Give discount on MP3 Player immediately!
Sell More: Give discount on Tennis Racket immediately!
Buy More: Order Laser Printer immediately!
The following example uses the ternary operator to concatenate every 2 lines from the items.txt file, with a comma in between. We discussed the awk ORS (output record separator) built-in variable earlier. In this example, the value of ORS is changed back and forth between comma and newline. When the line number modulo 2 (NR %2) produces a remainder (i.e. for odd lines) ORS is set to comma; otherwise it's a newline. So, lines 1 and 2 combine and print as a single line, lines 3 and 4 combine and print as a single line, and line 5 prints by itself, with a comma and no newline character. Print concatenated pairs of records:
$ awk 'ORS=NR%2?",":"\n"' items.txt
101,HD Camcorder,Video,210,10,102,Refrigerator,Appliance,850,2
103,MP3 Player,Audio,270,15,104,Tennis Racket,Sports,190,20
105,Laser Printer,Office,475,5,

71. Awk While Loop

Awk looping statements are used to perform a set of actions again and again in succession. Awk keeps executing a statement as long as the loop condition is true. Just like a C program, awk supports various looping statements. First, let us look at the While loop statement. Syntax:
while(condition)
actions
  • while is awk keyword.
  • condition is conditional expression.
  • actions are the body of the while loop. If there are more than one action, the actions must be enclosed within curly braces.
The awk while loop checks the condition first; if the condition is true, it executes the actions. After executing all the actions, the condition is checked again, and if it is true, the actions are performed again. This process is repeated until the condition becomes false. Please note that if the condition returns false in the first iteration, the actions are never executed. The example below uses the BEGIN block that gets executed before anything else in an Awk program. The awk while loop appends the character ‘x’ to the variable ‘string’ 50 times. The variable count is post-incremented each time it is checked, and the actions are performed if it was less than 50 before being incremented. So the loop executes exactly 50 times. After the loop, the value of the ‘string’ variable is printed.
$ awk 'BEGIN { while (count++<50) string=string "x"; print string }'
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
The following awk program prints the total number of items sold from the items-sold.txt file for each item. For each line, the program has to add the values of field 2 through field 7. (Field 1 is the item number so its value is not added to the total). So, the while condition starts from 2nd field (as i=2 before while), and checks whether it has reached the last field in the record (i <= NF). N represents the total number of fields in the record.
$ cat while.awk
{
  i=2; total=0; 
  while (i <= NF) {
  total = total + $i;
  i++;
}
  print "Item", $1, ":", total, "quantities sold";
}

$ awk -f while.awk items-sold.txt
Item 101 : 47 quantities sold
Item 102 : 10 quantities sold
Item 103 : 65 quantities sold
Item 104 : 20 quantities sold
Item 105 : 42 quantities sold

72. Awk Do While Loop

The awk while loop is an entry-controlled loop, as the condition is checked at the entry. The do-while loop is an exit-controlled loop; the condition is checked at exit. The do-while loop always executes at least once; it repeats as long as the condition is true. Syntax:
do
action
while(condition)
In the example below, the print statement is executed exactly once because we ensure that the condition will be false. If this were a while statement, with the same initialization and condition, the actions would not be executed at all.
$ awk 'BEGIN{
  count=1;
  do
  print "This gets printed at least once";
  while(count!=1)
}'
This gets printed at least once
The following awk program prints the total number of quantities sold from the items-sold.txt file for each item. The output of this program is exactly the same as the while.awk program, but this uses do-while.
$ cat dowhile.awk
{
  i=2; total=0;
  do
{
total = total + $i;
i++;
} while (i <= NF)
  print "Item", $1, ":", total, "quantities sold";
}
$ awk -f dowhile.awk items-sold.txt
Item 101 : 47 quantities sold
Item 102 : 10 quantities sold
Item 103 : 65 quantities sold
Item 104 : 20 quantities sold
Item 105 : 42 quantities sold

73. Awk For Loop Statement

The awk for statement is functionally the same as the awk while loop, but the for statement syntax is much easier to use. Syntax:
for(initialization;condition;increment/decrement)
actions
The awk for statement starts by executing initialization, then checks the condition; if the condition is true, it executes the actions, then does the increment or decrement. As long as the condition is true, awk repeatedly executes the action and then the increment/decrement. The following example prints the sum of fields in a line. Initially the variable i is initialized to 1; if i is less than or equal to the total number of fields, the current field is added to the total; I is incremented and the test is repeated.
$ echo "1 2 3 4" | awk '{ for (i = 1; i <= NF; i++) total = total+$i }; END { print total }'
10
The following example prints all the fields in the file in the reverse order using a for loop. Please note that this uses decrement rather than increment in the for loop. Note: After reading in each line, Awk sets the NF variable to the number of fields found on that line. This example loops in reverse order starting from NF to 1 and outputs the fields one by one. It starts with field $NF, then $(NF-1),…, $1. After that it prints a newline character. Reverse For Example:
$ cat forreverse.awk
BEGIN {
  ORS="";
}
{
  for (i=NF; i >0; i--)
  print $i," "
  print "\n";
}

$ awk -f forreverse.awk items-sold.txt
12 10 8 5 10 2 101
2 0 3 4 1 0 102
13 5 20 11 6 10 103
5 6 0 4 3 2 104
6 12 7 5 2 10 105
Now we will present the for-loop version of the program we used to print the total quantity sold for each item in the items-sold.txt file. We previously showed a while-loop and do-while-loop version.
$ cat for.awk
{
  total=0;
  for (i=2; i <= NF; i++)
  total = total + $i;
  print "Item", $1, ":", total, "quantities sold";
}

$ awk -f for.awk items-sold.txt
Item 101 : 47 quantities sold
Item 102 : 10 quantities sold
Item 103 : 65 quantities sold
Item 104 : 20 quantities sold
Item 105 : 42 quantities sold

74. Awk Break Statement

The break statement is used for jumping out of the innermost loop (while, do-while, or for loop) that encloses it. Please note that the break statement has meaning only if you use it with in the loop. The following example prints any item number that has a month with no sold items, i.e. that has 0 for any one of the values field2 through field7.
$ cat break.awk
{
  i=2; total=0;
  while (i++ <= NF)
  if ($i == 0) {
    print "Item", $1, "had a month with no item sold"
    break;
  }
}

$ awk -f break.awk items-sold.txt
Item 102 had a month with no item sold
Item 104 had a month with no item sold
If you execute the following command, press Ctrl-C to stop the script and break out of it.
$ awk 'BEGIN{while(1) print "forever"}'
The above awk while loop prints the string “forever” forever, because the condition never fails. Usually this is not a good thing—although forever loops are used in process control or operating system applications! Let us modify the loop so that it executes exactly ten times and is terminated by a break statement.
$ awk 'BEGIN{
x=1;
while(1)
{
  print "Iteration";
  if ( x==10 )
  break;
  x++;
}}'
The above command produces the following output:
Iteration
..............
.........
Iteration

75. Awk Continue Statement

The continue statement skips over the rest of the loop body causing the next cycle around the loop to begin immediately. Please note that the continue statement has meaning only if you use it with in the loop. The following awk program prints the total number of quantities sold from the items-sold.txt file for each item. The output of this program is exactly same as the while.awk, dowhile.awk, and for.awk program, but this uses the while loop with continue instead of starting the loop at 2.
$ cat continue.awk
{
  i=1;
  total=0;
  while (i++ <= NF) {
    if (i == 1) continue;
    total = total + $i;
  }
  print "Item", $1, ":", total, "quantities sold";
}

$ awk -f continue.awk items-sold.txt
Item 101 : 47 quantities sold
Item 102 : 10 quantities sold
Item 103 : 65 quantities sold
Item 104 : 20 quantities sold
Item 105 : 42 quantities sold
The following awk script prints the value of x at each iteration except the 5th, where a continue statement skips the printing.
awk 'BEGIN{
x=1;
while(x<=10)
{
if(x==5){
x++;
continue;
}
print "Value of x",x;x++;
}
}'
The above command produces the following output.
Value of x 1
Value of x 2
Value of x 3
Value of x 4
Value of x 6
Value of x 7
Value of x 8
Value of x 9
Value of x 10

76. Awk Exit Statement

The exit statement causes the script to immediately stop executing the current commands, and also ignores the remaining lines from the input file. Exit accepts any integer as an argument which will be the exit status code for the awk process. If no argument is supplied, exit returns status zero. The following awk script exits during the 5th iteration. Since the print statement is after the exit statement, the value of x is printed only till 4, and once it reaches 5 awk exits.
$ awk 'BEGIN{
x=1;
while(x<=10)
{
if(x==5){
exit;}
print "Value of x",x;x++;
}
}'
The above command produces the following output.
Value of x 1
Value of x 2
Value of x 3
Value of x 4
The following example prints the first item number that has a month when no items were sold. This is similar to the break.awk example, except that it exits when it finds a month with no sales for an item, rather than going on to look at the other items.
$ cat exit.awk
{
  i=2; total=0;
  while (i++ <= NF)
  if ($i == 0) {
    print "Item", $1, "had a month with no item sold"
    exit;
  }
}

$ awk -f exit.awk items-sold.txt
Item 102 had a month with no item sold
Note: Item 104 also had a month with no item sold. But, it was not displayed above, as we used exit in the while loop.