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

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

Жанры

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]) {

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

Товарищ "Чума" 10

lanpirot
10. Товарищ "Чума"
Фантастика:
городское фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Товарищ Чума 10

Вперед в прошлое 2

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

На границе империй. Том 7

INDIGO
7. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
6.75
рейтинг книги
На границе империй. Том 7

Седьмая встреча

Вассму Хербьёрг
Проза:
современная проза
4.00
рейтинг книги
Седьмая встреча

Моров. Том 5

Кощеев Владимир
4. Моров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Моров. Том 5

Вперед в прошлое 8

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

Демон-хранитель

TsissiBlack
Фантастика:
фэнтези
мистика
5.20
рейтинг книги
Демон-хранитель

Изгой

Майерс Александр
2. Династия
Фантастика:
фэнтези
попаданцы
рпг
аниме
5.00
рейтинг книги
Изгой

Изгой Проклятого Клана. Том 6

Пламенев Владимир
6. Изгой
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Изгой Проклятого Клана. Том 6

Газлайтер. Том 19

Володин Григорий Григорьевич
19. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Газлайтер. Том 19

Телохранитель Генсека. Том 3

Алмазный Петр
3. Медведев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Телохранитель Генсека. Том 3

Черный Маг Императора 16

Герда Александр
16. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 16

На границе империй. Том 6

INDIGO
6. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.31
рейтинг книги
На границе империй. Том 6

Законник Российской Империи

Ткачев Андрей Юрьевич
1. Словом и делом
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Законник Российской Империи