На следующем шаге требуется так изменить программу, чтобы искать сообщение с завтрашней датой так же, как и с сегодняшней. Наибольшие усилия затрачиваются на прибавление единицы к сегодняшнему числу. Но в конце месяца нужно перейти к следующему месяцу, а число приравнять единице. Конечно, число дней в разных месяцах различно. Именно здесь на помощь приходит ассоциативный массив. Два массива 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]) {
day2 = 1
mon2 = nextmon[mon1]
}
}
$1 == mon1 && $2 == day1 || $1 == mon2 && $2 == day2
' | mail $NAME
$
Обратите внимание на то, что Jan
появляется дважды в структуре данных; такое "сторожевое" значение упрощает обработку для декабря.
На последнем шаге нужно обеспечить запуск программы календаря на каждый день. Можно делать это и самому, не забывая задавать команду (каждый день!)
$ at 5 am
calendar
ctl-d
$
Однако такое решение нельзя считать автоматическим или надежным. Хитрость заключается в том, чтобы не только запустить программу calendar
, но и обеспечить следующий ее запуск.
$ cat early.morning
calendar
echo early morning | at 5am
$
Вторая строка файла early.morning
готовит еще одну команду at
для следующего дня, поэтому, раз начавшись, эта последовательность команд сама себя воспроизводит. В команде at
устанавливается PATH
, текущий каталог и другие параметры запускаемых ею команд, так что больше ничего и не требуется.
Измените программу calendar
так, чтобы она учитывала выходные дни: для пятницы "завтра" должно означать субботу, воскресенье или понедельник. Далее измените ее так, чтобы можно было учесть високосные годы. Следует ли учитывать праздники? Как бы вы это сделали?
Должна ли программа календарь учитывать даты, находящиеся в середине строки, а не только в ее начале? Как быть с датой, заданной в другом формате, например 10/1/83?
Почему в программе calendar
используется $NAME
, а не обращение к getname
?
Напишите вашу версию команды rm, которая не удаляет файлы, а пересылает их во временный каталог, используя команду at
для очистки каталога в то время, пока вы не работаете.
Язык awk
довольно громоздкий, и в рамках одной главы трудно показать все его возможности. Поэтому мы перечислим здесь еще ряд моментов, на которые необходимо обратить внимание в справочном руководстве:
• Переключение выходного потока оператора print
в файлы и программные каналы: за каждым оператором print
или printf
может следовать символ >
и имя файла (в виде строки в кавычках или переменной); выходной поток будет направлен в этот файл. Как и для интерпретатора, >>
означает добавление, а не запись. Для вывода в программный канал используется символ |
, а не >
.
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии