1. Среди всех шаблонов выделяют два необязательных специальных: BEGIN и END. Первый обрабатывается до чтения самой первой записи, второй — после чтения последней записи. Для этих шаблонов наличие части операция является обязательным. Шаблон BEGIN должен быть самым первым в сценарии, END — последним. Обычно шаблон BEGIN служит для объявления переменных и формирования заголовочной части документа. Шаблон END используется для формирования завершающей части.
Общий синтаксис этих правил:
BEGIN {действия}
другие правила
END {действия}.
Действия могут содержать список операторов и управляющих конструкций.
2. В качестве шаблона может быть указано расширенное регулярное выражение. Этим шаблоном обрабатываются только те строки, которые соответствуют регулярному выражению. Общий синтаксис правила в этом случае
[[номер_поля] [!]~] /рег_выражение/ [{действия}],
где номер_поля может быть $0, $1 и т.д., ~ — оператор сравнения с рег_выражением. Оператор отрицания ! используется для поиска записей, не соответствующих регулярному выражению.
Примеры правил:
/Sergei/ {print $2, $1} — для записей, которым соответствует регулярное выражение Sergei вывести сначала второе, а затем первое поле. Фактически сравнение происходит с выражением ^.*Sergei.*$, поэтому под это правило попадут и строки, содержащие, например, и Sergeichenko.
$3 ~ /[[:digit:]]/ {print $1} — для записей, третье поле которых содержит цифру, вывести первое поле.
И шаблон и действия могут содержать отношения (или их комбинацию. Общий синтаксис указания отношения
выражение1 оператор выражение2.
Выражение1 и выражение2 строятся с использованием указаний на поля в записи (рассмотрены выше), арифметических действий, предопределенных переменных и функций программы gawk и определенных пользователем переменных.
Арифметические операции:
+, -, *, /, %, ++, -- (сложение, вычитание, умножение, деление, остаток от деления, инкремент и декремент соответственно). Последние две операции могут быть как префиксными, так и постфиксными;
+=, *= — операторы составного присваивания.
Некоторые предопределенные переменные gawk:
FS — разделитель полей во входном потоке (по умолчанию пробел и табуляция);
OFS — разделитель полей в выходном потоке (по умолчанию пробел);
NR — номер текущей записи;
NF — число полей в текущей записи;
FILENAME — имя текущего обрабатываемого файла.
Некоторые предопределенные функции gawk:
length(строка) — возвращает длину строки. Если строка не указана, то длину записи;
substr(строка, n, m) — возвращает подстроку строки начиная с позиции n длиной m.
match(строка, рег_выражение) — возвращает позицию первого вхождения рег_выражения в строке, либо 0, если вхождений нет;
sub(рег_выражение, подстрока [, строка]) — заменяет первое вхождение рег_выражения на подстроку в строке. Если строка не указана, то замена производится в текущей записи.
Пользовательские (локальные) переменные можно объявить в виде
имя_переменной=значение.
Обращение к переменным не требует знака $ перед именем.
В качестве оператора обычно используют операторы сравнения: <, >, <=, ==, >=, != (меньше, больше, меньше или равно, равно, больше или равно, не равно соответственно).
Отношения можно комбинировать, используя логические операции && (логическое И), || (логическое ИЛИ), ! (логическое НЕ).
Пример 1:
$1>200 && $2=="Иванов" {print $0} — вывести записи, в которых значение первого поля больше 200, а второе соответствует текстовому значению Иванов.
Пример 2:
BEGIN {cost=0}
cost+=$2
END {print "Общая стоимость:", cost}
До просмотра всех записей переменной cost присваивается значение 0. Затем значение второго поля каждой записи прибавляется к значению переменной cost. После просмотра всех записей выводится сообщение и вычисленная сумма.
Замечание. Вторая строка является правилом, в котором имеется шаблон, но не имеется действий, поэтому на экран будут выведены все записи входного файла. Если заключить вторую строку в фигурные скобки, то правило будет иметь действия, но не будет иметь шаблона, поэтому на экран будет выведено лишь итоговое сообщение.
Пример 3:
Пусть записи входного файла состоят из пяти полей:
Фамилия Имя Отчество оклад должность.
Рассмотрим следующий сценарий.
BEGIN {z=0; n=0}
$5~/^[Мм]енеджер$/ {z+=$4; n++}
{sub ($2,substr($2,1,1)".")}
{sub ($3,substr($3,1,1)".")}
{print NR FS $0}
END {print "Средний оклад менеджера: " z/n}
В первом правиле инициализируются две пользовательские переменные. Во втором правиле определяется, что для записей, пятое поле которых начинается с «менеджер» (с маленькой или большой буквы), суммируется с добавлением сумма оклада, а счетчик количества менеджеров увеличивается на единицу. При выполнении этого правила на стандартный вывод ничего не выводится.
В третьем правиле производится замена имени (второго поля) на первую букву имени с добавлением точки (часть "."). Так как шаблонная часть отсутствует и в действиях нет команды вывода, то вывода информации не производится.
Четвертое правило аналогично третьему.
Пятое правило добавляет новое поле в выходной поток — номер записи, после которого следует разделитель полей и измененная запись.
Шестое правило выводит среднюю заработную плату менеджера.
В качестве действий могут выступать алгоритмические конструкции (if, for, while). Рассмотрим использование условной конструкции. Ее синтаксис
if (условие) {действия1} [else {действия2}].
Если условие истинно, то выполняются действия1, иначе — действия2. Часть else является необязательной. Если действия содержат по одной команде, фигурные скобки можно опустить.
Пример:
BEGIN {max=0}{
if ($2>max) {max=$2}
}
END {print "Максимальное количество баллов: " max}