Этот инструмент особенно удобно использовать для запоминания дней рождений и годовщин. Если вы забываете про важные события, приведенная ниже пара сценариев поможет вам избежать конфуза!
Листинг 3.12.Сценарий addagenda
··#!/bin/bash
··# addagenda — предлагает пользователю добавить новое событие для сценария agenda
··agendafile="$HOME/.agenda"
··isDayName()
··{
····# Возвращает 0, если все в порядке, 1 — в случае ошибки.
····case $(echo $1 | tr '[[: upper: ]]' '[[: lower: ]]') in
······sun*|mon*|tue*|wed*|thu*|fri*|sat*) retval=0;;
······*) retval=1;;
····esac
····return $retval
··}
··isMonthName()
··{
····case $(echo $1 | tr '[[: upper: ]]' '[[: lower: ]]') in
······jan*|feb*|mar*|apr*|may|jun*)··return 0;;
······jul*|aug*|sep*|oct*|nov*|dec*) return 0;;
······*) return 1;;
····esac
··}
··normalize()
··{
····# Возвращает строку с первым символом в верхнем регистре
····#·· и другими двумя — в нижнем.
····/bin/echo −n $1 | cut −c1 | tr '[[: lower: ]]' '[[: upper: ]]'
····echo $1 | cut −c2-3| tr '[[: upper: ]]' '[[: lower: ]]'
··}
··if [! -w $HOME]; then
····echo "$0: cannot write in your home directory ($HOME)" >&2
····exit 1
··fi
··echo "Agenda: The Unix Reminder Service"
··/bin/echo −n "Date of event (day mon, day month year, or dayname): "
··read word1 word2 word3 junk
··if isDayName $word1; then
····if [! -z "$word2"]; then
······echo "Bad dayname format: just specify the day name by itself." >&2
······exit 1
····fi
····date="$(normalize $word1)"
··else
····if [-z "$word2"]; then
······echo "Bad dayname format: unknown day name specified" >&2
······exit 1
····fi
····if [! -z "$(echo $word1|sed 's/[[: digit: ]]//g')"]; then
······echo "Bad date format: please specify day first, by day number" >&2
········exit 1
····fi
····if ["$word1" −lt 1 −o "$word1" −gt 31]; then
······echo "Bad date format: day number can only be in range 1-31" >&2
······exit 1
····fi
····if [! isMonthName $word2]; then
······echo "Bad date format: unknown month name specified." >&2
······exit 1
····fi
····word2="$(normalize $word2)"
····if [-z "$word3"]; then
······date="$word1$word2"
····else
······if [! -z "$(echo $word3|sed 's/[[: digit: ]]//g')"]; then
········echo "Bad date format: third field should be year." >&2
········exit 1
······elif [$word3 −lt 2000 −o $word3 −gt 2500]; then
········echo "Bad date format: year value should be 2000–2500" >&2
········exit 1
······fi
······date="$word1$word2$word3"
····fi
··fi
··/bin/echo −n "One-line description: "
··read description
··# Данные готовы к записи в файл
··echo "$(echo $date|sed 's/ //g')|$description" >> $agendafile
··exit 0
Второй сценарий, в листинге 3.13, короче, но используется чаще.
Листинг 3.13.Сценарий agenda, сопутствующий сценарию addagenda из листинга 3.12
··#!/bin/sh
··# agenda — сканирует файл. agenda в поисках записей, относящихся
··#·· к текущей дате
··agendafile="$HOME/.agenda"
··checkDate()
··{
····# Создать значения по умолчанию для сопоставления с текущей датой.
····weekday=$1 day=$2 month=$3 year=$4
····format1="$weekday" format2="$day$month" format3="$day$month$year"
····# И выполнить поиск среди записей в файле…
····IFS="|" # Команда read автоматически разбивает
············#·· прочитанные строки по символам в IFS.
····echo "On the agenda for today: "
····while read date description; do
······if ["$date" = "$format1" −o "$date" = "$format2" −o \
·········· "$date" = "$format3"]
······then
········echo " $description"
······fi
····done < $agendafile
··}
··if [! -e $agendafile]; then
····echo "$0: You don't seem to have an.agenda file. " >&2
····echo "To remedy this, please use 'addagenda' to add events" >&2
····exit 1
··fi
··# Получить текущую дату…
··eval $(date '+weekday="%a" month="%b" day="%e" year="%G"')
··day="$(echo $day|sed 's/ //g’)" # Удалить возможные пробелы в начале.
··checkDate $weekday $day $month $year
··exit 0
Сценарии addagenda и agenda поддерживают три типа событий: еженедельные («каждую среду»), ежегодные («каждого 3 августа») и однократные («1 января 2017»). В процессе добавления записей в файл событий их даты нормализуются и сжимаются так, что 3 August превращается в 3Aug, а Thursday превращается в Thu. Эта операция выполняется функцией normalize в сценарии addagenda
.
Читать дальше