Слайд 1
Условная выборка строк
Операторы-шаблоны, используемые для выбора строк, позволяют решать,
какие строки обрабатывать, а какие - игнорировать.
Пример.
Вывести все автомобили,
цены которых больше 3000$.
awk '$3 > 3000 {print $0}' cars.file
Оператор-действие выводит на экран все найденные автомобили
Оператор-шаблон выбирает строки, в которых цены больше 3000.
Слайд 2
Составные шаблоны
Для конструирования составных шаблонов можно использовать логические операции
и круглые скобки.
В этом случае могут применяться следующие символы:
~ - искать
по образцу;
// - для обозначения шаблона;
&& - логическая операция «И»;
II - логическая операция «ИЛИ»;
! - логическая операция «Отрицание».
Слайд 3
Примеры.
(NF < 3) || (NF > 4)
Этот шаблон соответствует
всем записям ввода, которые не имеют точно четырех полей.
Шаблон
/^[a-d].*/
эквивалентен шаблону /^a.*/ || /^b.*/ ||/^c.*/ ||/^d.*/
С помощью этого шаблона отыскиваются все строки, начинающиеся с символов a, b, c и d.
Слайд 4
Внимание! Шаблон диапазона
$1==2, $1==5
отличен от составного шаблона
$1>=2
&& $1
Слайд 5
А) Программа
awk ‘$1==3, $1==5’ file.me
выдаст результат:
Слайд 6
Б) Программа
awk ‘$1>=3 && $1
Слайд 7
Пример.
Вывести марки всех автомобилей фирмы "Ford", цены которых
находятся в пределах от 8000$ до 15000$ включительно.
cat > diapaz.car
$1~/Ford/
&& $3>=8000 && $3<=15000
{print $0} Ctrl-D
awk –f diapaz.car cars.file
Слайд 8
Операторы в awk
В программе awk возможно применение некоторых
сложных операторов.
В основном они совпадают с языком Си и
shell.
А) Оператор if - такой же, как и в Си
if (условие) оператор_1; [else оператор_2]
Если оператор_1 и оператор else находятся в одной строке, то они обязательно отделяются друг от друга символом “точка с запятой”.
Слайд 9
При выполнении более, чем одного оператора в оператор_1 или
в оператор_2 необходимо их заключать в фигурные скобки.
Условие ? оператор_1
: оператор_2
Если условие истинно, то выполняется оператор_1, иначе оператор_2.
Данный оператор удобен для вывода сообщений об ошибках.
Слайд 10
Б) Цикл for аналогичен в языке Си, но отличается от
цикла в языке shell:
for ( выражение_1; условие; выражение_2 )
{операторы}
for
(Var in Array) {операторы}
Во втором варианте оператора for переменная Var пробегает по индексам массива Array.
Слайд 11
В) Цикл while
while ( условие ) { операторы }
Г) Оператор break
вызывает немедленный выход из цикла while или for.
Д) Оператор continue инициирует
переход к следующему шагу цикла
(к условию в операторе while
или
к выражению_2 в опереторе for).
Слайд 12
Е) Опереатор next вызывает чтение следующей входной строки и сопоставление
ее с шаблонами в начале программы awk.
Ж) Оператор exit [статус] вызывает
немедленный переход на действия, определенные в шаблоне END.
Если шаблона END нет или в нем есть exit, то сценарий заканчивается сразу.
Если оператор exit применен без параметра, то он заканчивает программу со значением статуса, равным нулю, иначе – со значением вычисленного выражения параметра. Значение статуса присваивается встроенной переменной $?.
Слайд 13
Пример:
Вывести поля файла file1.me в обратном порядке.
awk ‘{for
(i=NF; i>0; --i); print $i}’ file1.me
Пример:
Вывести все строки
файла file2.me, находящиеся между парами start,stop.
awk ‘/start/,/stop/’ file2.me
Слайд 14
Дополнительные переменные
ARGC - количество аргументов командной строки.
ARGV - массив, содержащий аргументы
командной строки.
Индексы идут от 0 до ARGC – 1.
ARGV [0] – это всегда команда awk. Доступные опции UNIX не занимают массив ARGV.
FNR - номер текущей записи внутри файла ввода. Причем FNR <= NR.
Другими словами FNR ведет учет номера записи только текущего файла, а NR – номера строки всех файлов.
Слайд 15
Пример.
Пусть файл File.1 содержит три строки-записи, а файл
File.2– две.
Тогда команда
awk’{ print FNR NR}’ File.1 File.2
выведет следующие строки:
Слайд 16
FLENGTH - хранит значение длины строки сопоставления, производимого
функцией match().
FSTART -
хранит значение начала строки сопоставления, производимого
функцией match(). По значениям
FLENGTH и FSTART можно определить, что именно сопоставлялось.
SUBSEP - значение разделителя сценариев. По умолчанию хранит символ
двойных кавычек 0348, что эквивалентно 2810 или 1С16.
Слайд 17
ENVIRON - массив, содержащий значения текущих переменных окружения.
Индексы массива
– это имена самих переменных, а элементы массива – это
значения этих переменных. Для выделения названий и их значений удобно иcпользовать цикл for .. in.
Пример. Программа вывода листинга программ с номерами строк, если vi используется в качестве редактора по умолчанию.
ENVIRON[EDIDOR] == “vi” {print NR, $0};
Слайд 18
CONVFMT - формат преобразования чисел. Ее значение по умолчанию -
%6g.
Эта переменная обычно используется только для внутреннего применения.
FIELDWIDTHS - переменная
представляет возможность работы программисту с
полями фиксированной ширины, не привязываясь к отдельным символам разделителя полей.
Слайд 19
Если она определена, то считается, что все поля
имеют фиксированную ширину. В этом случае запись ввода разделяется с
использованием значений ширины поля, определенных в переменной FIELDWIDTHS.
При этом значение переменной FS не учитывается. Но в случае присваивания переменной FS нового значения, эта переменная отменяет использование переменной FIELDWIDTHS, и она восстанавливает значение по умолчанию.
Слайд 20
Значения переменной FIELDWIDTHS – числа, разделенные пробелами или табуляцией,
поэтому поля не обязательно должны быть одинаковой ширины.
Пример.
В файле
file.me первый символ обозначает “пол” человека. 0 - женщина, 1 – мужчина. Последний столбец - возраст служащих.
1Petrov, Ivan 24
1Ivanov, Petr 26
0Silina, Lina 25
Слайд 21
Проблема в следующем. Как отделить признак “пола” от фамилии?
Программа.
awk
‘{BEGIN { FIELDWIDTHS==1 7 1 4 1 2}
{if ($1==1)
{print $2,$4 “is male” $6 “years old.”
else
print $2,$4 “is female” $6 “years old.”
}
}
}’ file.me
Слайд 22
Здесь
1 – первое поле длиною 1;
7 – второе
поле длиною 7 (фамилия, запятая и пробелы);
1 – третье поле
длиною 1 (пробел);
4 – четвертое поле длиною 4 (имя);
1 – пятое поле длиною 1 (пробел);
2 – шестое поле длиною (возраст).
Внимание!
При использовании FIELDWIDTHS нельзя забывать ни об одном разделителе поля. Учитываются все пробелы между словами.
Слайд 23
IGNORECASE - управляет зависимостью регулярного выражения от регистра.
Если переменная
не равна нулю, то при проверки шаблона регистр не учитывается.
По умолчанию значение этой переменной равно нулю, то есть операции с регулярными выражениями зависят от регистра.
Слайд 24
Взаимодействие с интерпретатором
Вопрос в следующем, как передать программе на
awk значения переменных из командной строки?
Способ 1.
Аргументы командной строки
доступны в awk посредством встроенного массива ARGV. Переменная ARGC определяет количество аргументов в командной строке.
Слайд 25
Пример 1.
awk –f programfile In.file
В данном случае массив
ARGV будет иметь следующие значения:
ARGV[0] – awk
ARGV[1] – In.file
ARGC =
2
Так как не существует аргумента опций, то programfile не считается аргументом.
Если бы в командной строке была опция “–F,”, то массив ARGV не содержал бы также запятой.
Слайд 26
Способ 2.
Для передачи значений переменных надо присвоить значения
этим переменным, то есть необходимо или в командной строке или
в файле shell определить переменные и их значения.
awk –f programfile In.file X=1 FS=,
Пример 2
Сочетание программы shell и awk. Программа вводит значение переменной TZ в программу awk.
Слайд 27
echo $TZ
awk ‘/^”TZ”/ {print $1,$2}’ file.me TZ=”abcd”
Способ 3.
Предположим,
что мы хотим создать программу field N, которая печатает N-е
поле каждой входной строки так, чтобы можно было задать этот номер.
Hапример, в конвейере
who | field 1
будет печататься список имен, под которыми пользователь входит в систему.
Слайд 28
Язык awk может явно предоставлять возможность выбора полей. Hаша
задача - передать номер N программе awk.
Вариант 1.
awk ‘{print $
'$1'}’
Здесь $1 открыто (не внутри каких-либо кавычек), и поэтому становится номером поля, доступным в программе awk.
Вариант 2.
awk '{print \$$1}’
Аргумент обрабатывается интерпретатором и поэтому \$ становится просто $, а $1 заменяется на значение N
Слайд 29
Пример 3.
Создать программу addup, которая суммирует значение N-го
поля.
awk ‘{ S+= $'$1'} END {print S }’
Пример 4.
Создать
программу, которая вычисляет суммы значений каждого N-го поля и полную сумму.
Слайд 30
awk '{
BEGIN { N = '$1'}
{
for ( i
= 1; i
for ( i = 1; i <= N; i++)
printf "%6g ", Sum[i]
Total += Sum[i]
}
printf "; Total = %6g ", Total
}'
Слайд 31
Здесь шаблон BEGIN используется для засылки значения в переменную
N, чтобы не засорять конец программы кавычками.
Основная трудность во всех
этих примерах состоит не в том, что бы следить за кавычками ( хотя это дело очень хлопотливое), а в том, что программы, составленные таким образом, могут читать только свой стандартный входной поток.
Слайд 32
Здесь нет никаких возможностей передать им сразу и параметр
N и произвольно длинный список имен файлов.
Для этого необходима
определенная техника программирования на языке shell.
Слайд 33
Функции
Функции могут использоваться в любом месте, где может применяться
оператор-действие.
Функции имеют свободный формат, но должны разделяться точками с
запятой или символами новой строки.
Синтаксис определения функции следующий:
function Имя(Список_аргументов)
{Тело функции}
При объявлении функции в этой части Имя(Список нет пробела.
Слайд 34
Список аргументов идет через запятые. Это переменные, что используются
внутри функции.
Тело функции – это один или несколько операторов-действия.
Функции
вызываются из обычного оператора-действия.
ВНИМАНИЕ!
Левая скобка в списке параметров при определении и при обращении должна быть непосредственно за именем функции. (Для встроенных функций это может быть не так).
Слайд 35
Параметры функции передаются по значению, то есть действительные параметры
копируются и передаются формальным параметрам.
Пример.
Cat > is.awk
function is(x) { x=8
}
{ x=5; print x;
is(x); print x;
}
awk –f is.awk
Слайд 36
Результат будет:
5
5
Это происходит потому, что вызов функции is(x) копирует
значение в локальную переменную внутри самой функции.
Начальное значение равно
5 и оно не переопределяется значением 8.
Но если оператор поставить внутри функции, то будет напечатано и значение 8.
Слайд 37
Локальные переменные
Им не уделено особого внимания в awk. Поэтому
они должны быть перечислены в списке параметров.
Список локальных переменных
отделяется от параметров пробелом. Например:
function is(x A,B)
Здесь x - параметр подпрограммы, а A и B локальные переменные. Они существуют и имеют смысл до тех пор, пока функция is активна.
Слайд 38
Глобальные переменные
Любая переменная, что не входит в список параметров,
является глобальной.
Пример:
function is(x) {x=8; a=3}
{x=5; a=2; print “x= “ x
“a = “ a;
is(x); print “x= “ x “a = “ a;
}
При этом будет выдано:
x= 5 a = 2
x= 5 a = 3
Слайд 39
Обращение к функциям
- Функции могут вызывать друг друга.
- Обращение
к функции может быть рекурсивным.
В некоторых версиях awk можно использовать
слово func вместо function.
Встроенная функция system
Эта функция позволяет использовать команды UNIX и shell.
Слайд 40
Для этого необходимо выполнить:
system (value)
где value – строка,
что будет вводиться из командной строки UNIX. Текст должен быть
в двойных кавычках. Переменные должны идти через пробел для конкатенации.
Пример:
Файл file.me содержит:
file.1
file.2
file.3
Слайд 41
Тогда программа на awk будет иметь вид:
awk ‘{system (“cat”
$1)}’ file.me > file.your
В этом случае создается файл file.your, который
будет содержать полную копию всех трех файлов: file.1, file.2, file.3.
Слайд 42
CGI программирование
с применением shell и awk
Для изложения этого
материала необходимо повторить материал по:
протокол HTTP:
запрос;
ответ;
перенаправление.
интерфейс CGI:
Слайд 43
методы:
GET
POST
action:
адрес CGI скрипта.
Структура CGI скрипта:
заголовки HTTP протокола;
пустая строка;
тело запроса/ответа
скрипта.
Слайд 44
Пример 1.
Вывести значения некоторых переменных окружения Web-сервера.
Файл ENV-sh1.cgi
#!/bin/bash/
#
Указание для web-сервера, где находится
# shell-интерпретатор
echo “Content-type: text/html”
# Вывод
заголовка о типе ответа
echo “”
# Вывод пустой строки – разделитель
# заголовков и тела ответа. Это очень
# важная строка.
Слайд 45
echo “It is now `date`”
# вывод текщей даты
echo “QUERY_STRING
= $QUERY_STRING”
echo “REMOTE_HOST = $REMOTE_HOST”
echo “Your IP addresses is $REMOTE_ADDR”
exit
0
Для этой программы необходимо знать названия этих переменных окружения.
Слайд 46
Пример 2.
Вывести значения всех переменных окружения, включая переменные
Web-сервера.
Файл ENV-sh2.cgi
#!/bin/bash/
echo “Content-type: text/html”
echo “”
echo “”
echo “CGI test on shell
UNIX”
echo “”
echo “ CGI test on UNIX shell
”
Слайд 47
for i in `env`
# Операция `env` выдает значение
#
команды env
do
echo “$i
”
done
echo “”
exit 0
Слайд 48
Команда env:
выдает значения текущей рабочей среды окружения по одной
переменной в каждой строке в формате Имя_переменной=Значение_переменной
модифицирует среду для выполнения
команд, не влияя на текущее окружение.
В этом случае синтаксис команды env следующий:
env – Имя=Значение Команда
Слайд 49
Здесь:
опция “-“ ограничивает рабочую среду только теми переменными, что
есть в списке формата Имя=Значение.
Без опции “-“ команда env добавляет
этот список в рабочую среду.
Имя=Значение – список установок для выполняемой команды.
Команда – имя команды и ее аргументов для выполнения в указанной среде.
Слайд 50
Примеры:
env - выводит текущее окружение в формате Имя=Значение
env PATH=/usr/pmi
sh - запускает новый командный процессор с исходным каталогом /usr/pmi/
Слайд 51
Для метода GET наиболее важна переменная QUERY_STRING, содержащая в
формате
Имя_1=Значение_1&Имя_2=Значение_2&….
содержимое заполненной формы, которое
добавляется к URL.
Для метода POST важны
переменные:
- CONTENT_LENGTH - содержит число байтов в стандартном вводе;
- CONTENT_TYPE - содержит тип передаваемых данных от скрипта.
Слайд 52
Для распознавания метода передачи данных от формы применяется переменная
окружения REQUEST_METHOD, которая содержит значение “GET” для метода GET и
значение “POST” для метода POST.
При методе POST данные идут через стандартный ввод в формате, что и для метода GET.
В этом случае применяется команда read Var. При таком вызове в переменную Var попадает все, что идет до первого пробела в потоке стандартного ввода (STDIN).
Слайд 53
Но в силу того, что браузер передает информацию из
формы в закодированном виде, где все пробелы заменяются символами “+”,
то вся информация от формы будет проходить без всяких пробелов.
Если применена команда
read Var1, Var2, Var3, ….
то первое слово попадет в переменную Var1, второе – в Var2. Последней переменной достанется все, что останется в стандартном вводе (такой ввод для CGI не применяется).
Слайд 54
Пример:
В начале примера мы программируем на языке shell.
echo “Content-type:
text/html”
echo “”
echo “”
echo “CGI test on shell UNIX”
echo “”
echo “
CGI test on UNIX shell and awk”
Слайд 55
# Занесение в переменную Var1 данных от формы
if test
$REQUEST_METHOD = ”GET” then Var1=$QUERY_STRING
elif test $REQUEST_METHOD = ”POST” then
read Var1
fi
echo “Var1 = “ $Var1 “
”
# Образуем конвейер из shell и awk:
echo $Var1| awk ‘BEGIN {FS=”&”}
# Задание разделителя данных формы
массиве Arr пар Имя=значение
for (Name in Arr) {
print “Name =
“ Name “Value = “ Arr[Name] “
”}
}’
Получение массива Arr можно выполнить и так:
echo $Var1| awk ‘{ split ($0,Arr,”&”);
for (n in Arr) {print Arr[n]”
”}
}’