AWK
- Дата создания:
- 1977
- Создан под влиянием:
- Повлиял на:
- Парадигма:
- Типизация:
- Принятые расширения файлов:
- .awk
- Реализации и версии (свернуть все | развернуть все):
AWK (название происходит от первых букв фамилий авторов) — интерпретируемый скриптовый язык программирования, предназначенный для обработки текстовых данных.
AWK был создан в Bell Labs в 1977 году тремя авторами: Альфредом Ахо (Alfred Aho), Питером Вайнбергером (Peter Weinberger) и Брайаном Керниганом (Brian Kernighan). Эта версия языка вошла в Unix V7, выпущенный в 1979 году. В 1988 была выпущена книга “The AWK Programming Language”, в которой описывался новый диалект языка, вошедший в Unix SysV. Новый диалект был несовместим с исходным, и во избежание путанницы его называют nawk, или new awk, в то время как диалект 1977 года называют oawk, или old awk. nawk был выпущен под свободной лицензией в 1996 году и до сих пор поддерживается Керниганом.
В настоящее время AWK является одной из необходимых принадлежностей Unix-систем: вместе с Unix shell та или иная реализация AWK входит в стандартную поставку практически каждой Unix-подобной системы. Реализации AWK существуют для всех платформ.
Программа, написанная на AWK, принимает на вход поток текстовых данных (получаемых из файла или с консоли) и обрабатывает его построчно. Сама программа является набором правил вида “шаблон — действие”, где шаблон является регулярным выражением, а действие — последовательностью команд. Кроме того, программа может содержать определение пользовательских функций.
При обработке входного потока каждая строка данных сравнивается с каждым шаблоном, и выполняются действия тех правил, под шаблоны которых эта строка подходит. Шаблоны бывают следующих видов:
- шаблон из одного выражения: действие выполняется для тех строк, для которых значение выражения истинно.
- шаблон из пары выражений: действие выполняется для всех строк, начиная с той, для которой истинно первое выражение, и заканчивая той, для которой истинно второе.
- в шаблонах чаще всего используются выражения, основанные на регулярных выражениях.
-
специальные шаблоны
BEGINиENDзадают действия, которые выполняются до и после обработки входного потока, соответственно.
AWK позволяет обрабатывать каждую строку как целую строку (переменная $0) или как последовательность “полей” — подстрок, разделенных пробелами (переменные $1, $2, ...). Кроме этих встроенных переменных, доступен ряд других — количество прочитанных строк в файле NR, количество полей в текущей записи NF и т.д. Системные переменные позволяют настраивать режим обработки данных, например, задавать разделители записей и полей записи (по умолчанию — перенос строки и пробел).
AWK — динамически типизированный язык: все примитивные данные хранятся как строки, хотя могут обрабатываться как числа в зависимости от контекста их использования (например, в арифметических выражениях). Основная структура данных языка — ассоциативный массив с индексами-строками.
Среди недостатков языка называют:
-
необычную реализацию регулярных выражений — стандарт языка не позволяет извлечь из строки часть, соответствующую регулярному выражению (
gawkисправляет этот недочет). - невозможность повторно применить к строке один и тот же шаблон — это приходится программировать в явном виде. sed, послуживший одним из прообразов AWK, лишен этого недостатка.
- отсутствие возможности интерпретировать содержимое обрабатываемых строк как часть программы.
- необычный формат описания локальных переменных.
Элементы синтаксиса:
| Комментарий до конца строки | # |
|---|---|
| Регистрозависимость | да |
| Регулярное выражение идентификатора переменной | [_a-zA-Z][_a-zA-Z0-9]* |
| Присваивание значения переменной | varname = value |
| Объявление переменной | нет |
| Объявление переменной с присваиванием значения | нет |
| Группировка выражений | ( ... ) |
| Блок | { ... } |
| Равенство | a == b |
| Неравенство | a != b |
| Определение функции | function functionName(argname1, ..., argnameN) |
| Вызов функции | functionName(arg1, ..., argN) |
| Вызов функции без параметров | f() |
| Последовательность | ; или конец строки |
| Если - то | if (condition) trueBlock |
| Если - то - иначе | if (condition) trueBlock else falseBlock |
| Цикл с предусловием | while (condition) loopBody |
| Цикл с постусловием | do loopBody while (!c) |
| Цикл for - next для диапазона целых чисел с инкрементом на 1 | for (i = first; i <= last; i++) loopBody |
| Цикл for - next для диапазона целых чисел с декрементом на 1 | for (i = last; i >= first; i--) loopBody |
Примеры:
Hello, World!:
Пример для версий Jawk 1.02, gawk 3.1.6, mawk 1.3.3Печать выполняется шаблоном BEGIN, т.е. перед обработкой входных данных. Сами данные не обрабатываются.
BEGIN { print "Hello, World!" }
Факториал:
Пример для версий Jawk 1.02, gawk 3.1.6, mawk 1.3.3Используется итеративное определение факториала. Отдельные команды в пределах блока могут разделятся точками с запятой или переносами строк.
BEGIN {
f = 1
print "0! = " f
for (i=1; i<17; i++) {
f *= i
print i "! = " f
}
}
Числа Фибоначчи:
Пример для версий Jawk 1.02, gawk 3.1.6, mawk 1.3.3Используется итеративное определение чисел Фибоначчи. fib — ассоциативный массив, pr — строка.
BEGIN {
fib[1] = 1
fib[2] = 1
for (i=3; i<17; i++)
fib[i] = fib[i-1]+fib[i-2]
pr = ""
for (i=1; i<17; i++)
pr = pr fib[i] ", "
print pr "..."
}
Квадратное уравнение:
Пример для версий Jawk 1.02, gawk 3.1.6, mawk 1.3.3{ A = $1
B = $2
C = $3
if (A == 0)
print "Not a quadratic equation"
else
{ D = B*B-4*A*C
if (D == 0)
print "x = " (-B/2/A)
else if (D > 0)
{ print "x1 = " ((-B+sqrt(D))/2/A)
print "x2 = " ((-B-sqrt(D))/2/A)
}
else
{ print "x1 = (" (-B/2/A) "," (sqrt(-D)/2/A) ")"
print "x2 = (" (-B/2/A) "," (-sqrt(-D)/2/A) ")"
}
}
}
CamelCase:
Пример для версий gawk 3.1.6В переменной $0 хранится вся прочитанная запись-строка (в отличие от переменных $1, $2, …, в которых хранятся поля этой записи). Функция split разбивает строку text на фрагменты, разделенные строками, каждая из которых соответствует регулярному выражению, и записывает их в массив words. После этого каждый элемент words переводится в правильный регистр по частям функциями substr, toupper и tolower.
{ text = $0;
split(text, words, /[^a-zA-Z]+/);
for (i=1; i<=length(words); i++) {
res = res toupper(substr(words[i],1,1)) tolower(substr(words[i],2));
}
print res
}
CamelCase:
Пример для версий Jawk 1.02, gawk 3.1.6, mawk 1.3.3В реализации mawk нет функции length для определения количества элементов массива. В реализации Jawk ее также нельзя использовать — возникает ошибка “Cannot evaluate an unindexed array.”.
Вместо этого во всех реализациях можно использовать то, что функция split возвращает количество полученных ею фрагментов. В остальном этот пример аналогичен примеру для gawk.
{ text = $0;
N = split(text, words, /[^a-zA-Z]+/);
for (i=1; i<=N; i++) {
res = res toupper(substr(words[i],1,1)) tolower(substr(words[i],2));
}
print res
}
Комментарии
]]>blog comments powered by Disqus
]]>