Управляющие конструкции
awk позволяет использовать в действиях следующие управляющие конструкции:
if-else
while
for
и составной оператор, такой же, как в языке C.
Оператор if имеет следующий вид:
if ( условие ) оператор1 else оператор2
Условие вычисляется; если оно истинно, выполняется оператор1; в противном случае выполняется оператор2. Часть else является необязательной. Несколько операторов, заключенных в фигурные скобки, трактуются как единый оператор. В примере, приведенном в разделе Инициализация переменных, вычисление максимума населения можно перенести из шаблона в действие, если воспользоваться оператором if:
{ if (maxpop < $3) { maxpop = $3 country = $1 } } END { print country, maxpop }
Оператор while имеет вид:
while ( условие ) оператор
Условие вычисляется; если оно истинно, выполняется оператор. Условие вычисляется снова, и если оно истинно, опять выполняется оператор. Цикл повторяется до тех пор, пока условие истинно. Например, следующая программа распечатывает все входные поля, по одному на каждой строке:
{ i = 1 while (i <= NF) { print $i ++i } }
Другой пример - алгоритм Евклида нахождения наибольшего общего делителя $1 и $2:
{ printf "the greatest common divisor of " $1 "and ", $2, "is" while ($1 != $2) { if ($1 > $2) $1 -= $2 else $2 -= $1 } printf $1 "\n" }
Оператор for, аналогичный соответствующей конструкции языка C, имеет вид
for ( выражение1 ; условие ; выражение2 ) оператор
Так,
{ for (i = 1 ; i <= NF; i++) print $i }
- это еще одна awk-программа, распечатывающая все входные поля, по одному на каждой строке.
Имеется альтернативная форма оператора for, удобная для доступа к элементам ассоциативного массива в awk:
for ( i in массив ) оператор
Такая конструкция задает выполнение оператора для i, принимающего последовательно каждое значение индекса в массиве. Перебираются все индексы, однако порядок перебора не определен. Хаос гарантируется, если в теле цикла изменяется переменная i или создаются новые элементы массива. Цикл for в такой форме можно использовать, например, чтобы после завершения основной части программы напечатать все входные записи, предварив их порядковыми номерами:
{ x [NR] = $0 } END { for ( i in x) print i, x [i] }
Более содержательным является следующий пример - индексы-цепочки используются для вычисления суммарного населения стран по континентам:
BEGIN { FS="\t" } { population [$4] += $3 } END { for (i in population) print i, population [i] }
В данной программе тело цикла for выполняется для i, равного по очереди различным названиям континентов, до тех пор, пока все возможные значения i не будут исчерпаны (то есть пока все цепочки-названия не будут использованы). Отметим, однако, что порядок вычислений не определен. Например, такая программа может напечатать:
Africa 37 South America 142 Asia 1765 North America 243 Australia 14
Отметим, что условие в операторах if, while и for может включать:
- Операции сравнения <, <=, >, >=, ==, !=.
- Регулярные выражения, используемые вместе с операциями сопоставления ~ и !~.
- Логические операции , && и !.
- Скобки для группировки.
Оператор break (если он встречается внутри циклов while или for) приводит к немедленному выходу из цикла.
Оператор continue (если он встречается внутри циклов while или for) приводит к началу следующей итерации цикла.
Встретившийся в awk-программе оператор next заставляет awk немедленно перейти к следующей записи и возобновить просмотр шаблонов с начала программы. (Отметим различие между getline и next: getline не ведет к переходу к началу awk-программы.)
Если оператор exit встречается в секции BEGIN awk-программы, программа прекращает свое выполнение и выполняется секция END
(если она есть).
Если оператор exit встречается в основной секции awk-программы, прекращается выполнение основной секции. Последующие записи не читаются, выполняется секция END.
Оператор exit в секции END приводит к завершению выполнения программы.