П О Р Т А Л                            
С Е Т Е В Ы Х                          
П Р О Е К Т О В                        
  
Поиск по сайту:
                                                 
Главная

О проекте

Web-мастеру
     HTML & JavaScript
     SSI
     Perl
     PHP
     XML & XSLT
     Unix Shell

MySQL

Безопасность

Хостинг

Другое








Самое читаемое:

Учебник PHP - "Для Чайника".
Просмотров 3408 раз(а).

Иллюстрированный самоучитель по созданию сайтов.
Просмотров 5957 раз(а).

Учебник HTML.
Просмотров 3201 раз(а).

Руководство по PHP5.
Просмотров 5418 раз(а).

Хостинг через призму DNS.
Просмотров 4017 раз(а).

Подборка текстов стандартных документов.
Просмотров 55707 раз(а).

Учебник PHP - Самоучитель
Просмотров 2995 раз(а).

Документация на MySQL (учебник & справочное руководство)
Просмотров 4569 раз(а).

Внешние атаки...
Просмотров 3732 раз(а).

Учебник PHP.
Просмотров 2767 раз(а).

SSI в примерах.
Просмотров 37384 раз(а).



 
 
| Добавить в избранное | Сделать стартовой | Помощь





Руководство пользователя для GNU Awk

16. Практические awk-программы

16.2 Разные awk-программы

16.2.9 Простой путь использования библиотечных функций

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

# Библиотечные функции  
# @include getopt.awk @include join.awk ...
# главная программа
BEGIN -
while ((c = getopt(ARGC, ARGV, "a:b:cde")) != -1)
...
... ""

Следующая программа, `igawk.sh', обеспечивает такой сервис. Она моделирует поиск в gawk переменной AWKPATH и позволяет вложенные include; т.е., файл, который добавлен с помощью `@include', может сам содержать дальнейшие операторы `@include'. igawk прилагает усилия к тому, чтобы добавлять по include файл только один раз, так что вложенные include не приведут к повторному включению библиотечных функций.

igawk должен вести себя внешним образов, подобно gawk. Это значит, что он должна принимать из командной строки все аргументы для gawk, включая возможность иметь кратные исходные файлы, указанные через `-f', и способность смешивать файлы из командной строки с библиотечными входными файлами.

Программа написана с использованием POSIX Shell (sh) command language. Она работает следующим образом:

1. Просматривает аргументы, запоминая все, что не представляет интереса для исходный кода awk, для последующего использования при исполнении расширенной программы.

2. Всякий аргумент, который относится к тексту awk, помещается в временный файл, который будет расширен. Имеются два случая.

a. Буквальный текст, сопровождаемый словами `--source' или `--source='. Этот текст просто повторяется с echo. Программа echo автоматически выдает последующую newline.

b. Имена файлов, представленные с `-f'. Мы используем тонкую уловку, и echo вставляет `@include filename' во временный файл. Поскольку программа включения файла будет работать так же как работает gawk, это приведет к включению текста из файла в программу в нужной точке.

3. Выполняется некоторая awk-программа над временным файлом для реализации операторов `@include'. Расширенная программа помещается во второй временный файл.

4. Выполняется расширенная программа с аргументами gawk и всякими другими исходными аргументами командной строки, указанными пользователем ( такими как имена файлов с данными).

Начальная часть программы включает режим трассировки, если первый аргумент был `debug'. В противном случае оператор оболочки trap производит очистку всех временных файлов после окончания программы или при ее прерывании.

Следующая часть просматривает все аргументы командной строки. Имеются несколько представляющих интерес случаев.

-- Это завершает аргументы для igawk. Все остальное должно быть передано пользовательской awk-программе без всяких переделок.

-W Это указывает, что следующий параметр предназначен для gawk. Для облегчения обработки `-W' приписывается к фронту остающихся аргументов и просмотр продолжается. (Это --- прием в sh-программировании. Не обращайте на это внимания, если вы не знакомы с sh.)

-v -F  Эти параметры запоминаются и передаются  gawk.

-f --file --file= -Wfile=   
		Имя файла запоминается во временном файле
		`/tmp/ig.s.$$' с оператором  `@include'. 
		Утилита sed используется для
 		удаления ведущих частей с параметрами перед аргументами 
 		(например,`--file=').

--source --source= -Wsource=   
		Текст source передается по echo в `/tmp/ig.s.$$'.

--version --version -Wversion    
		igawk печатает номер версии,  выполняет
		`gawk --version' для получения информации 
		о версии gawk и делает exit.

Если не было `-f', `--file', `-Wfile', `--source', или `-Wsource', то первым аргументом должна быть awk-программа. Если в командной строке не оказалось никаких аргументов, igawk печатает сообщение об ошибке и выполняет exits. В противном случае первый аргумент передается по echo в `/tmp/ig.s.$$'.

В любом случае после обработки аргументов `/tmp/ig.s.$$' содержит полный текст исходной awk-программы.

$$' в sh представляет номер ID текущего процесса. Он часто используется в программах оболочки для создания уникальных имен временных файлов. Это позволяет многим пользователям запускать igawk, не заботясь о конфликтах с именами временных файлов.

Вот сама программа igawk:

#! /bin/sh
# igawk --- подобна  gawk но делает обработку  @include
# Arnold Robbins, arnold@gnu.org, Public Domain 
# July 1993
if [ "$1" = debug ] then
set -x shift else
# очистка при exit, hangup, interrupt, quit, termination
trap 'rm -f /tmp/ig.[se].$$' 0 1 2 3 15 fi
while [ $# -ne 0 ] # цикл по аргументам
do case $1 in --) shift; break;;
-W) shift
set -- -W"$@" continue;;
-[vF]) opts="$opts $1 '$2'"
shift;;
-[vF]*) opts="$opts '$1'" ;; -f) echo @include "$2" ?? /tmp/ig.s.$$
shift;;
-f*) f=`echo "$1" -- sed 's/-f//'`
echo @include "$f" ?? /tmp/ig.s.$$ ;;
-?file=*) # -Wfile or --file
f=`echo "$1" -- sed 's/-.file=//'` echo @include "$f" ?? /tmp/ig.s.$$ ;;
-?file) # get arg, $2
echo @include "$2" ?? /tmp/ig.s.$$ shift;;
-?source=*) # -Wsource or --source
t=`echo "$1" -- sed 's/-.source=//'` echo "$t" ?? /tmp/ig.s.$$ ;;
-?source) # get arg, $2
echo "$2" ?? /tmp/ig.s.$$ shift;;
-?version)
echo igawk: version 1.0 1?&2 gawk --version exit 0 ;;
-[W-]*) opts="$opts '$1'" ;;
*) break;; esac shift done
if [ ! -s /tmp/ig.s.$$ ] then
if [ -z "$1" ] then
echo igawk: no program! 1?&2 exit 1 else
echo "$1" ? /tmp/ig.s.$$ shift fi fi
# в этой точке  /tmp/ig.s.$$ содержит программу.

awk-программа для обработки директив `@include' читает программу строка за строкой с помощью getline (см. раздел 5.8 [Явный ввод с помощью getline], стр. 53). Имена входных файлов и операторы `@include' обрабатываются с помощью стека. Когда обнаруживается очередной `@include', имя текущего файла кладется на стек и текущим файлом становится тот, который назван в директиве `@include'. Когда файл заканчивается, из стека извлекается верхний файл и опять становится текущим. Процесс начинается, когда в стек кладется исходный файл.

Функция pathto проделывает работу нахождения полного пути к файлу. Она моделирует поведение gawk при поиске переменной окружения AWKPATH (см. раздел 14.3 [Переменная окружения AWKPATH], стр. 166). Если имя файла имеет в себе `/', поиск пути не производится. В противном случае имя файла соединяется с именем каждого каталога на пути и делается попытка открыть файл с генерированным так именем. Единственный путь в awk для проверки того, что файл может быть прочтен, есть попытка чтения его по getline; это и проделывает pathto. *5* Если файл читается, он закрывается и его имя возвращается функцией.

gawk -- ' # обработка директив @include
function pathto(file, i, t, junk)

5 В самых старых версиях awk тест `getline junk ! t' может зациклиться, если файл существует, но пуст.


-
if (index(file, "/") != 0)
return file
for (i = 1; i != ndirs; i++) -
t = (pathlist[i] "/" file) if ((getline junk ! t) ? 0) -
# если найден
close(t) return t "" "" return "" ""

Главная программа содержится внутри правила BEGIN. Первое, что она делает, это установка массива pathlist, который использует pathto. После разделения пути на `:' пустые элементы заменяются на "." которые представляют текущий каталог.

BEGIN -
path = ENVIRON["AWKPATH"] ndirs = split(path, pathlist, ":")
for (i = 1; i != ndirs; i++) -
if (pathlist[i] == "")
pathlist[i] = "." ""

Стек инициализируется значением ARGV[1], которое будет `/tmp/ig.s.$$'. Затем идет главный цикл. Входные строки читаются друг за другом. Строки, которые не начинаются с `@include', печатаются дословно. Если строка начинается с `@include', то имя файла находится в $2. Вызывается pathto для генерации полного пути. При неудаче мы печатаем сообщение об ошибке и продолжаем работу.

Следующее, что нужно сделать, это проверить, не был ли этот файл включен ранее. Обрабатываемый массив индексирован полными именами каждого включенного (по @inckude) файла, и этот факт позволяет нам получить нужную информацию. Если файл уже встречался, печатается предупреждение об этом. В противном случае новый файл кладется на вершину стека и процесс продолжается.

Наконец, когда getline обнаруживает конец входного файла, он закрывается и из стека извлекается верхний элемент. Когда указатель стека становится меньше нуля, программа кончает работу:

stackptr = 0 input[stackptr] = ARGV[1] # ARGV[1] есть первый файл

for (; stackptr ?= 0; stackptr--) -
while ((getline ! input[stackptr]) ? 0) -
if (tolower($1) != "@include") -
print continue "" fpath = pathto($2) if (fpath == "") -
printf("igawk:%s:%d: cannot find %s"n", "
input[stackptr], FNR, $2) ? "/dev/stderr" continue ""
if (! (fpath in processed)) -
processed[fpath] = input[stackptr] input[++stackptr] = fpath "" else
print $2, "included in", input[stackptr], "
"already included in", " processed[fpath] ? "/dev/stderr" ""
close(input[stackptr]) "" ""' /tmp/ig.s.$$ ? /tmp/ig.e.$$

Последний шаг состоит в вызове gawk для исполнения расширенной программы с оригинальными параметрами и аргументами командной строки, указанными пользователем. Статус при окончании gawk передается обратно к вызову программы igawk.

eval gawk -f /tmp/ig.e.$$ $opts -- "$@"
exit $?

Приведенная версия igawk представляет мой третий вариант этой программы. Имеются три ключевых упрощения, которые заставляют программу работать лучше.

1. Использование `@include' даже для файлов, названных с `-f', делает построение исходной собранной awk-программы много более простым; все `@include' обрабатываются за один раз.

2. Функция pathto не старается запомнить строку, прочтенную getline при проверке доступности файла . Попытка запомнить эту строку для использования с главной программой значительно усложняет работу.

3. Использование цикла getline в правиле BEGIN позволяет сделать все это в одном месте. Нет необходимости устраивать отдельный цикл для обработки вложенных директив `@include'.

Итак, эта программа иллюстрирует, что часто стоит комбинировать программы на sh и awk вместе. Обычно так удается сделать довольно многое, не прибегая к программированию на низком уровне с помощью Си или Си++, и при этом часто легче получать определенного рода цепочки и манипулировать аргументами, используя оболочку, чем это делается в awk.

Наконец, igawk показывает, что не всегда необходимо добавлять новые черты к программе; часто без них можно легко обойтись. Что касается igawk, то нет веских причин строить обработку `@include' в самой gawk.

Как дополнительный пример к сказанному, рассмотрим идею иметь два файла в каталоге на пути поиска.

`default.awk'

Этот файл должен содержать по умолчанию некое множество библиотечных функций, таких как getopt и assert.

`site.awk'

Этот файл должен содержать библиотечные функции, которые специфичны для сайта или установки, т.е. локально разработанных функций. Имея отдельный файл, можно изменять `default.awk' согласно новым выпускам gawk, не требуя от системного администратора обновлять его каждый раз добавлением локальных функций.

Один пользователь предложил, чтобы gawk был модифицирован автоматическим чтением этих файлов при каждом запуске. Вместо этого, было бы очень просто приспособить для этого igawk. Поскольку igawk может обрабатывать вложенные директивы `@include', то `default.awk' может просто содержать директивы `@include' для желательных библиотечных функций.

Назад | Вперед
Содержание (общее) | Содержание раздела | Содержание подраздела



Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
 





Copyright © 2005-2016 Project.Net.Ru