ОС Томск
.pdfshift ;;
-?) echo "$0: no option $1" exit ;;
*) if test $together = yes then
sort -u +1 -2 $1 | tr ... > /tmp/$0$$ if $print = no
then
cat /tmp/$0$$
else
lpr -c /tmp/$0$$
fi
rm /tmp/$0$$
|
exit |
else if test -s $1 |
|
then |
echo "no file $1" > &2 |
else |
sort +1 -2 $1 | tr...> /tmp/$0$$ |
if $print = no |
|
then |
cat /tmp/$0$$ |
else |
lpr -c /tmp/$0$$ |
fi |
|
|
rm /tmp/$0$$ |
fi shift fi;; esac done.
Процедура проверяет число параметров $# и, если оно равно нулю, завершается. В противном случае она обрабатывает параметры (оператор case). В качестве параметра может выступать либо ключ (символ, предваряемый минусом), либо имя файла (строка, представленная метасимволом *). Если ключ отличен от допустимого (метасимвол ? отличен от t и p), процедура завершается. Иначе в зависимости от наличия ключей t и p выполняются действия, заявленные в комментарии в начале процедуры.
90
Обработка прерываний в процедурах
Если при выполнении процедуры получен сигнал прерывания (от клавиши BREAK или DEL, например), то все созданные временные файлы останутся неудаленными (пока это не сделает администратор) ввиду немедленного прекращения процесса.
Лучшим решением является обработка прерываний внутри процедуры оператором trap:
Синтаксис:
trap 'command arguments' signals...
Кавычки формируют первый аргумент из нескольких команд, разделенных точкой с запятой. Они будут выполнены, если возникнет прерывание, указанное аргументами signals (целые):
2 - когда вы прерываете процесс; 1 - если вы "зависли" (отключены от системы) и др.
Пример (развитие предыдущего): case $1 in
.....
*) trap 'rm /tmp/*; exit' 2 1 (удаление временных файлов) if test -s $1
..............
rm /tmp/*
Лучше было бы:
trap 'rm /tmp/* > /dev/null; exit' 2 1
так как прерывание может случиться до того, как файл /tmp/$0$$ создан и аварийное сообщение об этом случае перенаправляется на null-устройство.
Выполнение арифметических операций: expr
Команда expr вычисляет значение выражения, поданного в качестве аргумента, и посылает результат на стандартный вывод. Наиболее интересным применением является выполнение операций над переменными языка Shell.
Пример суммирования 3 чисел:
91
$ cat sum3
expr $1 + $2 + $3 $ chmod 755 sum3 $ sum3 13 49 2
64
$
Пример непосредственного использования команды: $ expr 13 + 49 + 2 + 64 + 1
129
$
В expr можно применять следующие арифметические операторы: +, -, *, /, % (остаток). Все операнды и операции должны быть разделены пробелами.
Заметим, что знак умножения следует заключать в кавычки (одинарные или двойные), например: '*', так как символ * имеет в Shell специальный смысл.
Более сложный пример expr в процедуре (фрагмент): num = 'wc -l < $1'
tot = 100 count = $num
avint = 'expr $tot / $num' avdec = 'expr $tot % $num' while test $count -gt 0
do ...
Здесь wc -l осуществляет подсчет числа строк в файле, а далее это число используется в выражениях.
Отладка процедур Shell
Имеются три средства, позволяющие вести отладку процедур.
-Размещение в теле процедуры команд echo для выдачи сообщений, являющихся трассой выполнения процедуры.
-Опция -v (verbose = многословный) в команде Shell приводит к печати команды на экране перед ее выполнением.
92
-Опция -x (execute) в команде Shell приводит к печати команды на экране по мере ее выполнения с заменой всех переменных их значениями; это наиболее мощное средство.
Утилита AWK
Awk - утилита, подобная grep. Однако, кроме поиска по образцу, она позволяет проверять отношения между полями строк (записей) и выполнять некоторые действия над строками (генерировать отчеты). Название не является акронимом, оно образовано первыми буквами фамилий авторов (A.V.Aho,
P.Y.Weinberger, B.W.Kernighan).
Задание поиска-действия следует синтаксису: /<образец>/{<действие>}
И образец, и действие могут отсутствовать. Найденные по образцу строки при отсутствии заданного действия выводятся в стандартный вывод (на экран).
Образец задается регулярным выражением, как и в grep. Если образец отсутствует, обрабатываются все строки.
Рассмотрим примеры действий, которые можно выполнить командой awk.
Перестановка полей строки выполняется с помощью ссылки на поле $n, где n - номер поля.
Например: $ cat people
Mary Clark 101 Henry Morgan 112 Bill Williams 100
$ awk '{print $2 "," $1 "^I" $3}' people Clark, Mary 101
Morgan, Henry 112
Williams, Bill 100
где ^(control - I) - знак табуляции для подвода каретки к очередной позиции табуляции (для выравнивания третьего поля).
93
Действия для awk могут быть заданы в файле.
Например: $ cat swap
{print $2 "," $1 "^I" $3} $ awk -f swap people
Awk имеет встроенные образцы и переменные. Образцы BEGIN и END означают начало и конец файла соответственно. Переменная NR (Number of Records) означает число записей (строк) в файле, NF - число полей в записи. Можно использовать переменные, объявленные пользователем. Пример, подсчитывающий среднее значение третьего поля файла tennis (программа действий для awk - в файле average):
$ cat > average {total = total + $3}
END {print "Average value is", total/NR} ^D
$ awk -f average tennis Average value is 8.9
$
Образец поиска в awk может содержать условные выражения. Пример, в котором в файле tennis пишутся все записи, значение третьего поля в которых не меньше 10:
$ awk '$3 >= 10 {print $0}'tennis Steve Daniel 11
Hank Parker 18
Jack Austen 14
$
Знак $0 (доллар-ноль) есть ссылка на всю запись (строку). В общем случае выражение для условия подчиняется синтаксису, близкому к синтаксису выражений в языке C. Кроме того, в команде awk допустимо указывать отрезок образцов. Пример выборки всех записей, сделанных с 1976 до 1978 г.:
$ sort -n -o chard.s chard
94
$ awk '/1976/, /1978/ {if($2 < 8.00 print $0}' chard.s 1976 7.50 Chateau
1977 7.75 Chateau
1978 5.99 Charles
Как видно из примера, в программах действий для awk можно использовать управляющие структуры с синтаксисом, близким к языку C.
Пример цикла для печати полей всех записей файла в обратном порядке:
$ awk {for (i = NF; i > 0; --i) print $i} f1, где NF - число полей в записи.
Встроенные функции AWK
length(arg) - Функция длины arg. Если arg не указан, то выдает длину текущей строки.
exp(),log(),sqrt() - Математические функции экспонента, логарифм и квадратный корень.
int() - Функция целой части числа.
substr(s,m,n) - Возвращает подстроку строки s, начиная с позиции m, всего n символов.
index(s,t) - Возвращает начальную позицию подстроки t в строке s. (Или 0, если t в s не содержится.)
sprintf(fmt,exp1,exp2,...) - Осуществляет форматированную печать (вывод) в строку, идентично PRINTF.
split(s,array,sep) - Помещает поля строки s в массив array и возвращает число заполненных элементов массива. Если указан sep, то при анализе строки он понимается как разделитель.
Операции отношения awk
X = = Y – X равно Y? X ! = Y – X не равно Y?
X > Y – X больше чем Y?
X = > Y X больше чем или равно Y? X < Y – X меньше чем Y?
X < = Y – X меньше чем или равно Y?
X ~ Re – X совпадает с регулярным выражением Re?
95
X ! ~ Re – X не совпадает с регулярным выражением Re?
Старшинство операций в awk
Группа |
|
|
|
Операции |
|
|
|
|
1 |
= |
+= |
-= |
*= |
/= |
%= |
|
|
2 |
|| |
|
|
|
|
|
|
|
3 |
&& |
|
|
|
|
|
|
|
4 |
> |
>= |
< |
<= |
== |
!= |
~ |
!~ |
5 |
Строка конкатенации «x» «y» становится «xy» |
|
||||||
6 |
+ |
- |
|
|
|
|
|
|
7 |
* |
/ |
% |
|
|
|
|
|
8 |
++ |
-- |
|
|
|
|
|
|
Стандартные переменные
ARGC – число аргументов в командной строке; ARGV – массив с аргументами командной строки; FILENAME – строка текущего файла ввода;
FNR – номер текущей записи в текущем файле; FS – разделитель полей ввода;
NF – число полей в текущей записи; NR – номер текущей записи;
OFMT – формат вывода чисел (по умолчанию % 6g); OFS – разделитель полей ввода (по умолчанию пробел);
ORS – Разделитель выводимых записей (по умолчанию новая строка);
RS – Разделитель полей ввода (по умолчанию новая строка).
2.3 Список команд Shell
date — вывод даты;
who — вывод пользователей;
who am i— вывод собственного имени;
exit — выход из системы (для передачи кода завершения);
96
— |
почта; |
|
write |
— |
передача сообщения другому пользователю; |
man |
— |
информация о команде; |
news |
— |
новости; |
ed |
— |
текстовый редактор (a/... ./w имя/ctrl-d) |
ls |
— |
перечень имен файлов в каталоге; |
ls -t |
— |
перечень файлов во временном порядке; |
ls -l |
— |
перечень файлов в полном виде; |
ls -li |
— |
перечень файлов в расширенном виде; |
cat |
— |
распечатка файла (cat>имя — создание файла); |
pr |
— |
распечатка по 66 строк; |
mv |
— |
перенос файла; |
cp |
— |
копирование файла; |
rm |
— |
удаление файла; |
ln |
— |
назначение связи; |
rmdir |
— |
удалить каталог; |
mkdir |
— |
создать каталог; |
pwd |
— |
определение своего рабочего каталога; |
cd |
— |
смена каталога; |
wc |
— |
подсчет числа строк, слов и символов; |
tail +n |
— |
вывод файла начиная со строки с номером n; |
cmp |
— поиск различий между файлами (до первого |
|
различия); |
||
diff |
— поиск всех различий; |
|
echo |
— вывод строки (` ` — результата, ' ' — команды); |
|
echo $? — выдача кода завершения команды (0, 1, 2); |
||
wait |
— ждать завершения всех процессов; |
|
kill |
— убить процесс (kill -9 #_процесса); |
|
ps |
— список процессов; |
|
nohup |
— |
выполнение команды после отключения (nohup |
кмд&); |
|
|
nice |
— запуск с пониженным приоритетом (nice кмд&); |
|
at |
— запуск в определенное время (at команды ctrl-d); |
|
export |
— сообщение интерпретатору о использовании |
|
переменных; |
||
sh |
— переход в порожденный shell; |
|
du |
— определение занятого пространства; |
|
|
|
97 |
df |
— свободное пространство диска; |
chmod |
— смена права доступа; |
mesg |
— (n — запрет, y — разрешение) сообщения; |
sleep |
— пауза; |
set |
— показать все ранее определенные переменные; |
set `` |
— установить значение переменной; |
time |
— информация о времени выполнения команды; |
uname |
— информация о системе (uname -a — полная); |
read |
— присваивает переменной значение последующей |
строки; |
|
touch |
— заменяет время модификации файла на настоящее; |
for |
— цикл (for i in список/ do команды/ done); |
case |
— выбор (case слово in/шаблон) команды ;;/esac); |
if |
— условие (if команда / then команды, если условие |
верно / else команды, если условие ложно/fi; |
|
while |
— цикл (while команда/do тело цикла, выполняется пока |
команда возвращает истина/done; |
|
until |
— цикл (аналог while, но ждет ложь); |
trap |
— последовательность действий выполняемая при |
прерывании (trap 'rm -f $old; exit 1' 1 2 15), где |
|
|
0 — выход из интерпретатора |
|
1 — отбой |
|
2 — прерывание (DEL) |
|
3 — останов (ctrl-\; вызывает распечатку содержимого |
памяти программы) |
|
|
9 — уничтожение |
|
15 — окончание выполнения. |
Встроенные переменные интерпретатора |
|
$# |
— число аргументов; |
$* |
— все аргументы, передаваемые интерпретатору ($@); |
$- |
— флаги передаваемые интерпретатору; |
$? |
— возвращение значения последней выполненной |
команды; |
|
$$ |
— номер процесса интерпретатора; |
|
98 |
$! — номер процесса последней команды, запущенной с &;
Правила сопоставления шаблонов в интерпретаторе
* — задание любой строки, в том числе и пустой.
?— любой одиночный символ;
"..." — задает в точности ...; ""('') защищает от спецсимволов; \c — задает с буквально;
a|b — только для выражения выбора, a или b.
Значения переменных
$var — значение var;
${var-thing} — значение var, если оно определено, в противном случае thing;
${var=thing} — значение var, если var не определено, то присваивается значение thing;
${var?строка} — если var определено — $var, в противном случае выводится строка и инт. прекращает работу; ${var+thing} — thing, если $var определено, в противном случае ничего.
Метасимволы
| — конвейер (связь выходного потока одной программы с выходным потоком другой);
&— асинхронный запуск;
; — последовательное выполнение; > — помещение выходного потока; >> — добавление выходного потока; * — любая строка;
?— любой символ;
[ccc] — задает любой символ из [ссс] в имени файла; `...` — инициирует выполнение команды;
( ) — инициирует выполнение команды в порожденном shell;
{ } — инициирует выполнение команды в текущем shell;
99
