Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СППО - Лабораторные работы.doc
Скачиваний:
22
Добавлен:
10.11.2019
Размер:
752.13 Кб
Скачать

Лабораторная работа №17. Язык обработки шаблонов gawk

Цель работы: освоить базовые принципы работы с языком обработки шаблонов gawk.

Необходимые сведения

Язык gawk является C-подобным скриптовым языком обработки структурированных текстовых файлов, состоящих из записей (текстовых строк, оканчивающихся символом новой строки), каждая из которых, в свою очередь, рассматривается как набор полей с разделителями между ними.

Утилита gawk последовательно просматривает все записи входного файла на соответствие некоторому шаблону (регулярному выражению, условию и пр.) и для записей, соответствующих шаблону, выполняет указанные пользователем действия.

Совокупность шаблона и связанных с ним действий называют правилом обработки записей. Обычно таких правил несколько и для удобства их помещают в текстовый файл, называемый сценарием gawk. Сама утилита gawk запускается командой

gawk –f сценарий [текстовый_файл].

Ключ -f указывает, что правила обработки записей содержатся в файле сценария. Утилита gawk не изменяет исходного текстового_файла; результат направляется в стандартный поток вывода. Если текстовый_файл не указан, то данные поступают со стандартного ввода.

Сценарий gawk имеет следующую структуру (часть правила, заключенная в квадратные скобки может отсутствовать):

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

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

...

Если шаблон не указан, то действия применяются ко всем записям текстового файла, записи по умолчанию не выводятся. Если действия не указаны, то выводятся все записи, соответствующие шаблону. Сами действия обязательно заключаются в фигурные скобки.

Для шаблона может быть указано несколько действий. Они указываются либо в одной строке через ; (точка с запятой), либо каждое действие в новой строке. В последнем случае рекомендуется использовать C-подобный синтаксис. Например, запись правила

шаблон {действие1; действие2; … ; действиеN}

эквивалентна записи

шаблон {

действие1

действие2

действиеN}

В шаблонах и действиях можно ссылаться на поля текущей просматриваемой записи: $1 соответствует первому полю, $2 — второму и т.д. Чтобы сослаться на текущую запись целиком (т.е. на все поля записи), указывают $0. Разделителем полей по умолчанию считается пробел. Если используется другой разделитель, то gawk нужно запустить с ключом -F новый_разделитель.

Наиболее часто в качестве действия выступает команда вывода print. При указании без аргументов выводится текущая запись целиком. Если используется синтаксис

print арг1 арг2 … аргN,

то происходит конкатенация аргументов. Если используется синтаксис

print арг1, арг2, … аргN,

то аргументы выводятся через разделитель вывода (пробел по умолчанию).

Описание шаблонной части правила gawk-сценария

  1. Среди всех шаблонов выделяют два необязательных специальных: BEGIN и END. Первый обрабатывается до чтения самой первой записи, второй — после чтения последней записи. Для этих шаблонов наличие части операция является обязательным. Шаблон BEGIN должен быть самым первым в сценарии, END — последним. Обычно шаблон BEGIN служит для объявления переменных и формирования заголовочной части документа. Шаблон END используется для формирования завершающей части.

Общий синтаксис этих правил:

BEGIN {действия}

другие правила

END {действия}.

Действия могут содержать список операторов и управляющих конструкций.

  1. В качестве шаблона может быть указано расширенное регулярное выражение. Этим шаблоном обрабатываются только те строки, которые соответствуют регулярному выражению. Общий синтаксис правила в этом случае

[[номер_поля] [!]~] /рег_выражение/ [{действия}],

где номер_поля может быть $0, $1 и т.д., ~ — оператор сравнения с рег_выражением. Оператор отрицания ! используется для поиска несоответствия регулярному выражению.

Примеры правил:

/Sergei/ {print $2, $1} — для записей, которым соответствует регулярное выражение Sergei вывести сначала второе, а затем первое поле. Фактически сравнение происходит с выражением ^.*Sergei.*$, поэтому под это правило попадут и строки, содержащие, например, и Sergeichenko.

$0 ~ /Sergei/ {print $2, $1} — аналогично предыдущему правилу.

$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}

В первом правиле инициализируются две пользовательские переменные. Во втором правиле определяется, что для записей, пятое поле которых начинается с «менеджер» (с маленькой или большой буквы), суммируется с добавлением сумма оклада, а счетчик количества менеджеров увеличивается на единицу. При выполнении второго поля ничего не выводится.

В третьем правиле производится замена фамилии (второго поля) на первую букву фамилии с добавлением точки (часть "."). Так как шаблонная часть отсутствует и в действиях нет команды вывода, то вывода информации не производится.

Четвертое правило аналогично третьему.

Пятое правило добавляет новое поле в выходной поток — номер записи, после которого следует разделитель полей и измененная запись.

Шестое правило выводит среднюю заработную плату менеджера.

  1. В качестве шаблона может выступать алгоритмическая конструкция (if, for, while). Рассмотрим использование условной конструкции. Ее синтаксис