Чтение онлайн

на главную - закладки

Жанры

UNIX — универсальная среда программирования
Шрифт:

awk "{print \$$1}"

Аргумент обрабатывается интерпретатором, поэтому

\$
становится
$
, а
$1
заменяется на значение
n
. Мы предпочитаем решение с апострофами (одиночными кавычками), поскольку при использовании кавычек в типичной программе
awk
появится слишком много символов
\
.

Другим примером может служить программа

addup n
, суммирующая значения n-го поля:

awk '{s += $'$1'}

END {print s}'

В третьем примере вычисляются

отдельные суммы значений каждого n-го поля и полная сумма:

awk '

BEGIN { n = '$1' }

{ for (i=1; i <= n; i++)

sum[i] += $1

}

END { for(i = 1; i <= n; i++)

{

printf "%6g ", sum[i]

total += sum[i]

}

printf "; total = %6g ", total

}'

Нам удобнее было использовать часть

BEGIN
для засылки значения в переменную
n
, чем засорять конец программы кавычками.

Основная трудность во всех приведенных выше примерах состоит не в том, чтобы следить за кавычками (хотя и это хлопотно), а в том, что программы, составленные показанным способом, могут читать только свой стандартный входной поток. Нет никакой возможности передать им сразу и параметр

n
, и произвольно длинный список имен файлов. Для этого требуется определенная техника программирования на языке
shell
; которую мы рассмотрим в следующей главе.

Служебная программа-календарь на языке
awk

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

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

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

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

calendar
в каталоге
/usr/you
:

$ cat calendar

Sep 30 день рождения мамы

Oct 1 обед с Джо, полдень

Oct 1 встреча в 16:00

$

Далее, необходимо уметь просматривать календарь, отыскивая определенную дату. Существует масса вариантов; мы остановимся на языке

awk
, поскольку с его помощью легче выполнять арифметические операции по переходу от одной даты к другой, однако для этой цели подходят и другие программы, например
sed
и
egrep
. Конечно, строки, выбранные из файла
calendar
, посылаются командой
mail
.

Наконец, вам придется научиться автоматически и безотказно просматривать календарь каждый день, скажем, рано утром. Это можно сделать с помощью команды

at
, о которой упоминалось в гл. 1.

Если ограничить календарь таким форматом, в котором каждая строка начинается с названия месяца и числа (как это делает команда

date
),
то составить первый вариант программы календаря нетрудно:

$ date

Thu Sep 29 15:23:12 EDT 1983

$ cat bin/calendar

# calendar: version 1 - today only

awk <$HOME/calendar '

 BEGIN { split ("'"`date`"'", date) }

 $1 == date[2] && $2 == date[3]

' | mail $NAME

$

Функция в части

BEGIN
разбивает дату, выдаваемую командой
date
, и заносит ее в массив; второй и третий элементы массива — месяц и число. Мы предполагаем, что в переменной интерпретатора
NAME
находится имя, под которым вы вошли в систему. Вы заметили, какая нужна сложная последовательность кавычек, чтобы "поймать" результат действия команды
date
в середине строки программы
awk
. Более простым решением является передача даты в первой строке входного потока:

$ cat /bin/calendar

# calendar: version 2 - today only, no quotes

(date; cat $HOME/calendar) |

awk '

 NR == 1 { mon = $2; day = $3 } # set the date

 NR > 1 && $1 == mon && $2 == day # print calendar lines

' | mail $NAME

$

На следующем шаге требуется так изменить программу, чтобы искать сообщение с завтрашней датой так же, как и с сегодняшней. Наибольшие усилия затрачиваются на прибавление единицы к сегодняшнему числу. Но в конце месяца нужно перейти к следующему месяцу, а число приравнять единице. Конечно, число дней в разных месяцах различно. Именно здесь на помощь приходит ассоциативный массив. Два массива

days
и
nextmon
, индексами которых служат названия месяцев, содержат число дней месяца и название следующего месяца. Например,
days["Jan"]
равно 31, a
nextmon["Jan"]
есть
Feb
. Вместо того чтобы написать множество операторов типа

days["Jan"] = 31; nextmon["Jan"] = "Feb"

days["Feb"] = 28; nextmon["Feb"] = "Mar"

...

мы воспользуемся функцией

split
для преобразования удобно записываемой структуры данных в то, что требуется:

$ cat calendar

# calendar: version 3 -- today and tomorrow

awk <$HOME/calendar '

BEGIN {

 x = "Jan 31 Feb 28 Mar 31 Apr 30 May 31 Jun 30 " \

"Jul 31 Aug 31 Sep 30 Oct 31 Nov 30 Dec 31 Jan 31"

 split(x, data)

 for (i = 1; i < 24; i += 2) {

days[data[i]] = data[i+1]

nextmon[data[i]] = data[i+2]

 }

 split("'"`date`", date)

 mon1 = date[2]; day1 = date[3]

 mon2 = mon1; day2 = day1 + 1

 if (day1 >= days[mon1]) {

Поделиться:
Популярные книги

Стеллар. Трибут

Прокофьев Роман Юрьевич
2. Стеллар
Фантастика:
боевая фантастика
рпг
8.75
рейтинг книги
Стеллар. Трибут

Его огонь горит для меня. Том 2

Муратова Ульяна
2. Мир Карастели
Фантастика:
юмористическая фантастика
5.40
рейтинг книги
Его огонь горит для меня. Том 2

На границе империй. Том 9. Часть 4

INDIGO
17. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 4

Наследник

Кулаков Алексей Иванович
1. Рюрикова кровь
Фантастика:
научная фантастика
попаданцы
альтернативная история
8.69
рейтинг книги
Наследник

Совершенно несекретно

Иванов Дмитрий
15. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Совершенно несекретно

Ваше Сиятельство 2

Моури Эрли
2. Ваше Сиятельство
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Ваше Сиятельство 2

Прометей: каменный век II

Рави Ивар
2. Прометей
Фантастика:
альтернативная история
7.40
рейтинг книги
Прометей: каменный век II

Единственная для темного эльфа 3

Мазарин Ан
3. Мир Верея. Драконья невеста
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Единственная для темного эльфа 3

Жандарм

Семин Никита
1. Жандарм
Фантастика:
попаданцы
альтернативная история
аниме
4.11
рейтинг книги
Жандарм

Долгий путь домой

Русич Антон
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
6.20
рейтинг книги
Долгий путь домой

Прогрессор поневоле

Распопов Дмитрий Викторович
2. Фараон
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прогрессор поневоле

Наследие Маозари 6

Панежин Евгений
6. Наследие Маозари
Фантастика:
попаданцы
постапокалипсис
рпг
фэнтези
эпическая фантастика
5.00
рейтинг книги
Наследие Маозари 6

Я еще не барон

Дрейк Сириус
1. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я еще не барон

Лолита

Набоков Владимир Владимирович
Проза:
классическая проза
современная проза
8.05
рейтинг книги
Лолита