awk поддерживает операторы if-else, while, do-while аналогично языку программирования Си.
Синтаксис оператора if:
if (выражение) оператор_1 else оператор_2
"выражение" является условным и не имеет ограничений. Оно может включать операторы отношений:
<, <=, >, >=, ==, !=
регулярные выражения:
~, !~
логические операторы:
||, &&, !
операторы слияния и круглые скобки для группирования.
В операторе if awk сначала вычисляет "выражение". Если оно не ноль и не пустое, то оператор_1 выполняется, в противном случае выполняется оператор_2. Часть else не является обязательной.
Одиночный оператор всегда может быть заменен на набор операторов, заключенных в скобки. Каждый оператор в наборе отделяется от другого символом новой строки или точкой с запятой.
Возьмем файл countries и вычислим максимальное население с помощью оператора if:
{ if (maxpop < $3) { maxpop = $3 country = $1 } } END { print country, maxpop }
Синтаксис оператора while:
while (выражение) оператор
Оценивается "выражение": если оно не ноль и не пусто, то выполняется "оператор" и "выражение" вновь тестируется. Цикл повторяется до тех пор, пока "выражение" не примет значение ноль. Например, чтобы напечатать все поля вводного файла через строчку:
{ i = 1 while ( i <= NF ) { print $i i++ } }
Синтаксис оператора for:
for(выражение_1; выражение; выражение_2) оператор
Он аналогичен следующей последовательности:
выражение_1 while ( выражение) { оператор выражение_2 }
Синтаксис оператора do:
do оператор while (выражение)
Оператор выполняется до тех пор, пока "выражение" не станет равным нулю. Тестирование проводится после выполнения "оператора", т.е. в конце цикла. Как правило оператор do используется реже, чем while или for.
Оператор break приводит к немедленному выходу из while или for; чтобы продолжить оператор, надо начать новую итерацию.
Следующий оператор заставит awk перейти к новой записи и начать поиск шаблона, начиная с первого оператора "шаблон-действие".
Оператор exit завершает программу; ввод больше не считывается и действие END выполняется, если оно есть в программе.
exit expr
приводит к тому, что программа возвращает значение "expr" как состояние выхода. Если "expr" в строке нет, то состояние exit равно нулю.
awk поддерживает одномерные массивы. Массивы и элементы массивов нет необходимости объявлять. Индексы массива могут быть числом или строкой. Пример условного обозначения числового индекса:
x[NR] = $0
присваивает текущую строку вводного файла элементу NR массива x.
Фактически возможно считать целый вводной файл в массив с помощью программы awk:
{ x[NR] = $0 } END { ... обработка ...}
Первое действие только записывает каждую строку вводного файла, отмеченную номером строки, в массив x, обработка выполняется в операторе END.
Элементы массива могут именоваться с помощью нецифровых величин. Например, следующая программа накапливает общее количество населения Asia и Africa в соответствующий массив pop. Оператор END печатает общее количество населения этих двух континентов.
/Asia/ { pop["Asia"] += $3 } /Africa/ { pop["Africa"] += $3 } END { print "Asian population in million is", pop[Asia] print "African population in million is", pop[Africa] }
Результат получим следующий:
Asian population in million is 1765 African population in million is 37
В этой программе, если вы воспользуетесь pop[Asia] вместо pop["Asia"], то выражение будет использовать значение переменной как индекса, и так как значение переменной не установлено, то количество населения будет накапливаться в pop[""].
Предположим, нужно определить общую площадь каждого континента из файла countries.
Каждое выражение может быть использовано как индекс при ссылке в массиве. Так:
area[ $4 ] += $2
использует строку в 4-м поле текущей записи вводного файла для индексирования массива area, накапливая значение второго поля:
BEGIN { FS = "\t" } { area[$4] += $2 } END { for (name in area) print name, area[name] }
Относительно файла countries получим результат:
Asia 13611 North America 7467 South America 4358 Australia 2968 Africa 1888
Эта программа использует следующую форму оператора, который организует итерации для нахождения индекса в массиве:
for ( i in array ) оператор
выполняется "оператор" с переменной i , для которой определен array[i]. Цикл выполняется для каждого определенного индекса, который выбирается в произвольном порядке.
awk не поддерживает многомерные массивы, но допускает список индексов. Они объединяются в один индекс значениями, разделенными строкой (хранимой в переменной SUBSEP).
Например:
for ( i = 1; i <= 10; i++ ) for ( j = 1; j <= 10; j++ ) arr[i, j] = ...
создает массив, который ведет себя как двумерный массив. Индексом является сочетание i, SUBSEP и j.
Вы можете определить, появляется ли конкретное i в массиве arr:
if ( "Africa" in arrea ) ...
Это условие приведет к выполнению тестирования без создания массива ["Africa"]. Этот массив создался, бы если использовалось
if ( area ["Africa"] != "" ) ...
Возможно также разбить любую строку на поля, которые станут элементами массива. Это можно сделать с помощью встроенной функции split:
split ( "s1:s2:s3", a, ":" )
split разбивает строку на 3 поля, используя в качестве разделителя ":" и сохраняя s1 в [1], s2 - в [2], s3 - в [3]. Возвращаемое значение этого оператора равно числу полей, т.е. трем. Третий аргумент функции split - это регулярное выражение, будет использоваться как поле разделителя. Если третий аргумент отсутствует, то в качестве поля разделителя будет использоваться FS.
Массив элементов может быть разделен с помощью аргумента delete: