Определения функций могут располагаться где угодно между правилами программы awk. Таким образом, общая форма программы awk расширяется и включает последовательности правил и определений функций пользователя. Нет необходимости помещать определения функций перед обращениями к ним, так как awk читает всю программу перед началом ее выполнения.
Определение функции с именем name выглядит так:
function name(parameter-list) -
body-of-function ""
name есть имя определяемой функции. Правильное имя функции подобно правильному имени переменной: последовательность букв, цифр и подчеркиваний, начинающаяся не с цифры. В пределах одной awk-программы каждое имя может быть использовано как переменная, массив или функция.
parameter-list есть список аргументов функции и локальных имен переменных, разделенных запятыми. Когда функция вызывается, имена аргументов используются для помещения значений аргументов, указанных в вызове. Локальные переменные инициализируются пустыми цепочками. Функция не может иметь двух параметров с одинаковыми именами.
Тело функции состоит из операторов awk. Это наиболее важная часть определения, так как она говорит, что функция должна делать. Имена аргументов существуют, чтобы дать телу возможность различать аргументы; локальные переменные предоставляют телу места для временных значений. Синтаксически имена аргументов неотличимы от имен локальных переменных; вместо этого, количество аргументов, указанных в вызове функции, определяет, как много имеется аргументных переменных. Так, если даны три значения аргументов, первые три имени в списке параметров есть аргументы, а остальные являются локальными переменными. Если количество аргументов не одно и тоже во всех вызовах функции, некоторые имена в списке параметров могут быть аргументами в одних случаях и локальными переменными в других. Иначе говоря, можно считать, что опущенные аргументы по умолчанию получают значение пустой цепочки.
Обычно, когда вы пишите функцию, вы знаете, сколько имен вы намерены использовать для аргументов и сколько для локальных переменных. При программировании обычно помещают несколько дополнительных пробелов между аргументами и локальными переменными для указания того, как функция будет использоваться. Во время выполнения тела функции аргументы и значения локальных переменных прячут, или затеняют, те же самые имена, использованные в остальной программе. Затененные переменные недоступны из определения функции, потому что невозможно обратиться к ним, пока их имена заняты локальными переменными. Все другие переменные, используемые в awk-программе, доступны для ссылок или присваиваний из тела функции. Аргументы и локальные переменные играют особую роль только на время выполнения тела функции. Как только оно окончено, можно опять обращаться к переменным, которые были затенены при выполнении тела.
Тело функции может содержать выражения, которые вызывают функции. Они могут даже вызывать определяемую функцию, или непосредственно или через вызов другой функции. Мы говорим в таких случаях, что функция рекурсивна.
Во многих реализациях awk, включая gawk, ключевое слово function может быть сокращено до func. Однако POSIX указывает только слово function. Фактически это имеет некоторые практические следствия. Если gawk находится в POSIX-совместимом режиме (см. раздел 14.1 [Параметры командной строки], стр. 161), то следующий оператор не определяет функцию:
func foo() - a = sqrt($1) ; print a ""
Он определяет правило, которое для каждой записи сцепляет значение переменной `func' с возвращенным значением функции `foo'. Если цепочка-результат не пуста, действие выполняется. И это, конечно, будет не то, что задумано. (awk принимает такой ввод как синтаксически правильный, поскольку функции могут использоваться раньше их определения в программах.) Для обеспечения переносимости программ употребляйте всегда в определениях ключевое слово function.