Язык обработки шаблонов AWK

Название AWK произошло из инициалов его разработчиков: Alfred V. Aho, Peter J. Weinberger и Brian W. Kernighan.

AWK рассматривает входной поток как список записей. Каждая запись делится на поля. На основе этой информации выполняется некоторый определённый программистом алгоритм обработки. По умолчанию разделителем записей является символ новой строки. Разделителем полей — символ пробела или табуляции, или последовательность таких символов. Символы-разделители можно явно определить в программе. Символ-разделитель полей можно определить и в командной строке.

Структура awk-программы

Программа состоит из операторов, имеющих вид:

шаблон {действие}

или

шаблон — когда выводятся строки с данным шаблоном.

или

{действие} — когда действие выполняется для всех строк.

Действие состоит из последовательности операторов, разделённых точкой с запятой (;), символом перевода строки или закрывающейся скобкой.

Для дальнейших примеров будем использовать файл следующего содержания:

$ cat awk_test Иванов К.И. 1980 50 Петров А.П. 1978 40 Сидоров С.Л. 1979 40 Федоров Л.Е. 1970 65

Примеры

Выводим весь текст

$ awk '{print}' awk_test Иванов К.И. 1980 50 Петров А.П. 1978 40 Сидоров С.Л. 1979 40 Федоров Л.Е. 1970 65

Выводим строки в которых встречается сочетание букв ро

$ awk '/ро/ {print}' awk_test Петров А.П. 1978 40 Сидоров С.Л. 1979 40 Федоров Л.Е. 1970 65

то же самое

$ awk '/ро/ {}' awk_test Петров А.П. 1978 40 Сидоров С.Л. 1979 40 Федоров Л.Е. 1970 65

END и BEGIN

В AWK есть два оператора специального вида: BEGIN — начальные установки
и
END — действия, выполняемые после обработки последней записи входного потока.

BEGIN {действие} шаблон {действие} шаблон {действие} . . . END {действие}

Вызов AWK

Существуют два основных варианта:

Первый
awk [-Fc] ‘script.awk’ [файлы]

В этом случае программа заключенная в одинарные кавычки находятся в теле команды
-Fc — флаг, меняющий стандартный разделитель полей на c
файл — имя файла исходных данных, при его отсутствии данные читаются со стандартного входа.
Примеры:

$ cat awk_test | awk '/ро/ {print}'

и

$ awk '/ро/ {print}' < awk_test

дают результат, аналогичный

$ awk '/ро/ {print}' awk_test

Примеры, демонстрирующие обращение с тазделителями:
В этом примере команда выводит вторые($2) поля строк, содержащих ро

$ awk '/ро/ {print $2}' awk_test А.П. С.Л. Л.Е.

В этом примере программа работает со строками, содержащими число 40, и использует в качестве разделителя полей цифру 9

$ awk -F9 '/40/ {print $2}' awk_test 78 40 7
Второй
awk [-Fc] -f script.awk [файлы]

Флаг -f указывает на awk-скрипт

Переменные и выражения

В языке awk выделяют две группы переменных:

  1. Предопределенные
  2. Декларированные в программе.

Исходные значения предопределенных переменных устанавливаются интерпретатором awk в процессе запуска и выполнения awk-программы.
К предопределенным относятся:

 NR        номер текущей строки;              значение по-умолчанию
NF        число полей в текущей строке;
RS        разделитель строк на вводе;              "\\0"
FS        разделитель полей на вводе;      пробел и/или табуляция
ORS       разделитель строк на выводе;              RS
OFS       разделитель полей на выводе;              FS
OFMT      формат вывода чиcла;                     "%.6g"
FILENAME  имя входного файла.

Прочим переменным пользователь может присваивать начальные значения. По умолчанию "0" или пустая строка
Типы переменных:

  • позиционные
  • числа с плавающей точкой
  • строка символов
  • массив

Интерпретатор awk рассматривает переменную как строковую, пока не возникает необходимость выполнить операции:

  • если пробел (конкатенация), то строки;
  • если +, то числа с плавающей точкой.

Примеры:

$ awk '{a = $3 $4; print a}' awk_test 198050 197840 197940 197065 $ awk '{a = $3+$4; print a}' awk_test 2030 2018 2019 2035 $ awk '{} END{a = 2+ "2"; print a}' awk_test 4 $ awk '{} END{a = 2+2; print a}' awk_test 4 $ awk '{} END{a = 2+ "два"; print a}' awk_test 2 $ awk '{} END{a = "два" + "два"; print a}' awk_test 0 $ awk '{} END{a = 2.3+2.000; print a}' awk_test 4.3

Массив не объявляется, а начинает существовать в момент первого использования. Индекс массива — любое ненулевое значение или строка. Массивы ассоциативные, т.е. не по вычисляемому индексу, а по совпадению содержания, например:

     day [Jan][31] = Mon
day [Feb][01] = Tue
day [Feb][02] = Wed

Массивы удобно использовать при суммированиях, например:

$ cat file John 100 Mary 200 Mary 200 John 100 John 300 $ $ awk '{sum[$1] += $2; print $1 "_" sum[$1]}' file John_100 Mary_200 Mary_400 John_200 John_500

Операции, подобные Си

=, +=, -=, *=, /=, %=, +, /, %, ++, --.

Сравнения чисел

<, <=, ==, !=, >=, >
Если хоть один аргумент - строка, то происходит сравнение строк.

Логические операции

!, ||, &&
Операция пробел - конкатенация.

Примеры awk-программ

$ awk '{print $2, $3}' awk_test К.И. 1980 А.П. 1978 С.Л. 1979 Л.Е. 1970 $ awk '/е/ {print $2, $3}' awk_test А.П. 1978 Л.Е. 1970 $ awk '/е/ {print $2, 2000-$3}' awk_test А.П. 22 Л.Е. 30 $ awk '{ s = s + $4} END {print ("Суммарный возраст:" s); print ("Средний возраст:" s/NR)}' awk_test Суммарный возраст: 195 Средний возраст: 48.75 $ awk '{ s += $4 } {print("NR="NR, "NF="NF)} END {print ("FILENAME=" FILENAME); print ("Значение позиционной переменной" $4 "\"пусто\" после окончания просмотра)"); print ("Суммарный возраст:" s); print ("Средний возраст:" s/NR)}' awk_test NR=1 NF=4 NR=2 NF=4 NR=3 NF=4 NR=4 NF=4 FILENAME=awk_test Значение позиционной переменной65"пусто" после окончания просмотра) Суммарный возраст:195 Средний возраст:48.75

Селекторы

Здесь селектор — расширение понятия шаблон, поскольку там где в структуре команды указан шаблон, в общем случае может стоять любой селектор.
ЗАМЕЧАНИЕ — Открывающая скобка действия { должна быть в строке селектора.
В качестве селектора может быть:

  1. выражение
  2. шаблон
  3. их комбинация

Примеры:

выражение

 $3 != $4 && $3 > 1970
$3 % 2 == 1
$1=="Иванов" - (кавычки, чтобы воспринималось, как строка.)


шаблон

 /ab/ отлично от /a b/, / ab/ и /ab /
номер_поля %$@~*!G4;:%#`шаблон   - по совпадению
номер_поля !%$@~*!G4;:%#`шаблон  - по несовпадению
$ awk '$3~0 {print}' awk_test Иванов К.И. 1980 50 Федоров Л.Е. 1970 65 $ awk '$3!~0 {print}' awk_test Петров А.П. 1978 40 Сидоров С.Л. 1979 40

Шаблон может формировать множество образцов или указывать, в каком месте поля искать:

  • /%$@~*!G4;:%#`a/ --- поле начинается с a
  • /a$/ --- поле кончается a
  • \+ --- экранирует оператор +
  • [abc] --- любой из символов a, b и c
  • [a-р] --- любой символ диапазона
  • * --- 0 или больше вхождений регулярного выражения
  • + --- 1 или больше вхождений регулярного выражения
  • ? --- 0 или 1 вхождение регулярного выражения
  • ab|cd --- ab или cd

Примеры:

$ awk '$3~/(7[0-9])$/ {print}' awk_test Петров А.П. 1978 40 Сидоров С.Л. 1979 40 Федоров Л.Е. 1970 65 $ awk '$1=="Иванов" {print}' awk_test Иванов К.И. 1980 50 $ awk '$4/2==25 {print}' awk_test Иванов К.И. 1980 50 $ awk '$3 != $4 && $3 > 1970 {print}' awk_test Иванов К.И. 1980 50 Петров А.П. 1978 40 Сидоров С.Л. 1979 40 $ awk '$1~/нов$/ {print}' awk_test Иванов К.И. 1980 50 $ awk '/%$@~*!G4;:%#`Ив|дор/ {print}' awk_test Иванов К.И. 1980 50 Сидоров С.Л. 1979 40 Федоров Л.Е. 1970 65 $ awk '/1980/,/1979/ {print}' awk_test Иванов К.И. 1980 50 Петров А.П. 1978 40 Сидоров С.Л. 1979 40

Часть_2 >>