Руководство пользователя для GNU Awk
8. Образцы и действия
8.1 Элементы образцов
8.1.5 Специальные образцы BEGIN и END
BEGIN и END служат специальными образцами. Они не используются для сравнения с входными записями. Они обеспечивают стартовые или заключительные действия в сценарии awk.
8.1.5.1 Стартовые и заключительные действия
Правило BEGIN выполняется один раз, до чтения первой входной записи. Правило END выполняется один раз, после прочтения всего ввода.
Например:
$ awk ' ? BEGIN - print "Analysis of ""foo""" "" ? /foo/ - ++n "" ? END&
- print """foo"" appears " n " times." ""' BBS-list
a Analysis of "foo"
a "foo" appears 4 times.
Эта программа определяет количество записей в входном файле `BBS-list', которые содержат цепочки `foo'. Правило BEGIN печатает заголовок отчета. Нет нужды использовать правило BEGIN для инициализации счетчика n нулем, так как awk делает это автоматически (см. раздел 7.3 [Переменные], стр. 79). Второе правило увеличивает переменную n каждый раз, когда читается запись, содержащая образец `foo'. Правило END печатает значение n в конце работы.
Специальные образцы BEGIN и END не могут использоваться в диапазонах или в булевских операторах (вернее, они не могут использоваться ни с какими операторами).
Одна awk-программа может иметь много BEGIN и/или END правил. Они выполняются в порядке их расположения, все правила BEGIN при старте и все правила END при окончании. BEGIN и END правила могут перемежаться с другими правилами. Эта возможность была добавлена в awk-версии 1987 и входит в стандарт POSIX. Оригинальная (1978) версия awk требует помещать правило BEGIN в начале программы, а правило END в конце, и допускает только по одному каждого вида. Этого больше не требуется, но это рекомендуется для лучшей организации и читаемости программы.
Кратные правила BEGIN и END полезны при написании библиотечных функций, поскольку каждый библиотечный файл может иметь свое собственное правило BEGIN и/или END для собственной инициализации и/или завершения. Заметим, что порядок, в котором библиотечные функции называются в командной строке, определяет порядок, в котором выполняются их правила BEGIN и END. Поэтому нужно писать эти правила в библиотечном файле так, чтобы порядок их исполнения был безразличен. См. раздел 14.1 [Параметры командной строки], стр. 161, о подробностях использования библиотечных функций. См. главу 15 [Библиотека функций awk], стр. 169, содержащей сведения о многих библиотечных функциях.
Если awk-программа имеет только правило BEGIN и никаких других правил, то она заканчивается после выполнения правила BEGIN. (Начальная версия продолжала чтение до конца файла, игнорируя входные данные.) Однако если существует правило END, ввод читается даже если в программе нет других правил. Это необходимо в случае, когда правило END проверяет переменные FNR и NR (d.c.).
Правила BEGIN и END должны иметь действия; для них не предусмотрены действия по умолчанию, поскольку при их исполнении нет никаких текущих записей.
8.1.5.2 Ввод/вывод из правил BEGIN и END
Имеется несколько вопросов (иногда тонких), связанных с I/O в правилах BEGIN или END. Первый из них относится к значению $0 в правиле BEGIN. Так как правила BEGIN выполняются до чтения всякого ввода, то в это время еще нет входной записи и никаких полей. Ссылки на $0 и поля дают пустые цепочки или нули, в зависимости от контекста. Один способ придать $0 реальное значение состоит в выполнении команды getline без переменной (см. раздел 5.8 [Явный ввод с помощью getline], стр. 53). Другой путь состоит в присваивании ей некоторого значения.
Другой вопрос подобен первому, но относится к противоположному концу. Какое значение имеют внутри правила END переменные $0 и NF? Традиционно считалось, что $0 и NF неопределенны внутри правила END. В стандарте POSIX указано, что NF указывает количество полей в последней входной записи. По-видимому по недосмотру в стандарте не указано, что $0 также сохраняет значение последней записи. gawk оставляет это значения для использования в правиле END. Но знайте, что Unix awk и, возможно, другие реализации этого не делают.
Третий вопрос вытекает из двух первых. Каков смысл `print' внутри правил BEGIN или END? Обычно его смысл `print $0'. Если $0 есть пустая цепочка, то печатается пустая строка. Издавна программисты awk употребляют `print' в правилах BEGIN и END в смысле `print ""', уповая на то, что $0 пуста. Хотя вы об этом можете не заботиться в правиле BEGIN, во всяком случае в gawk, это не приведет к добру в END. И это плохой стиль. Если вы хотите получить пустую строку в выводе, это всегда можно сделать явным образом.
Назад | Вперед
Содержание (общее) | Содержание раздела | Содержание подраздела
Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
|