Язык обработки шаблонов 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] — любой из символов ab и 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 >>