Руководство пользователя для GNU Awk
10. Встроенные переменныеЭффективное AWK-программирование
Большинство awk-переменных доступны вам для использования в нужных вам целях; они изменяются только вашей программой и никогда не влияют ни на что кроме условий, проверяемых вашей программой. Но несколько переменных в awk имеют специальное назначение. Некоторые из них awk автоматически проверяет, так что они позволяют вам сообщать интерпретатору определенную информацию. Другие awk автоматически устанавливает, так что они несут информацию от awk к вашей программе. В этой главе описаны все встроенные переменные gawk. Большинство из них описываются также в главах, касающихся их областей активности. 10.1 Встроенные переменные, которые управляют действиями awkПриведем алфавитный список переменных, которые вы можете изменять для контроля за некоторыми действиями awk. Переменные, специфичные для gawk, помечены звездочками `*'. CONVFMTЭта цепочка управляет превращениями чисел в цепочки (см. раздел 7.4 [Конверсии цепочек и чисел], стр. 81). Она работает в качестве первого аргумента функции sprintf (см. раздел 12.3 [Встроенные функции для манипуляций с цепочками], стр. 137). Ее значение по умолчанию есть "%.6g". CONVFMT была введена в стандарте POSIX. FIELDWIDTHS *Это разделенный пробелами список столбцов, который сообщает gawk, как расщеплять ввод с фиксированными границами для колонок. Это экспериментальная возможность. Присваивание в FIELDWIDTHS отменяет использование FS для разделения полей. См. раздел 5.6 [Чтение данных фиксированной ширины], стр. 49, содержащий детали. Если gawk работает в режиме совместимости (см. раздел 14.1 [Параметры командной строки], стр.161), то FIELDWIDTHS не оказывает специального влияния и операции по выделению полей производятся только на основе значения FS. FSFS представляет входной разделитель полей (см. раздел 5.5 [Указания того, как разделяются поля], стр. 44). Ее значение есть одно-символьная цепочка или много символьное регулярное выражение, которое соответствует разделителям между полями в входной записи. Если значение есть пустая строка (""), то каждый символ в записи рассматривается как отдельное поле. Значение ее по умолчанию есть " ", цепочка из одного пробела. Как специальное исключение, это значение подразумевает, что всякая последовательность пробелов, символов табуляции и/или newlines есть отдельный разделитель. Оно также побуждает игнорировать пробелы, знаки табуляции и newlines в начале и конце записи. Значение FS можно устанавливать из командной строки с помощью параметра `-F': awk -F, 'program' input-filesЕсли gawk использует FIELDWIDTHS для разделения полей, то присваивание значения переменной FS заставит gawk возвратиться к нормальному, на основе FS, разделению полей. Простой путь для этого просто написать `FS = FS', возможно, с пояснительным комментарием. IGNORECASE *Если значение IGNORECASE не ноль и не пусто, то все сравнения цепочек и определения соответствий регулярным выражениям будут независимы от регистра. Так, в соответствие regexp по `~' и `!~', функция gensub, gsub, index, match, split и sub, в окончаниях записей по RS и разделению полей по FS --- всюду будет игнорироваться регистр во всех операциях. Значение IGNORECASE не влияет на индексацию в массивах. См. раздел 4.5 [Чувствительность к регистру в соответствиях], стр. 33. Если gawk работает в режиме совместимости, (см. раздел 14.1 [Параметры командной строки], стр.161), то IGNORECASE не имеет специального значения и цепочки и операции с regexp чувствительны к регистру. OFMTЭта цепочка управляет превращениями чисел в цепочки (см. раздел 7.4 [конверсии цепочек и чисел], стр. 81) при печати по оператору print. Фактически она работает как первый аргумент функции sprintf (см. раздел 12.3 [Встроенные функции для манипуляций с цепочками], стр. 137). Ее значение по умолчанию есть "%.6g". Ранние версии awk также использовали OFMT для спецификации формата при превращении чисел в цепочки в общих выражениях; теперь это делается согласно переменной CONVFMT. OFSЭто выходной разделитель полей (см. раздел 6.3 [Выходные разделители], стр. 63). Он разделяет поля на выходе в операторе печати. По умолчанию имеет значение " ", цепочка из одного пробела. ORS Это выходной разделитель записей. Он выдается в конце результата оператора печати. По умолчанию его значение есть ""n". (См. раздел 6.3 [Выходной разделитель, стр. 63.) RSЭто входной разделитель записей в awk. По умолчанию его значение есть цепочка из одного символа newline. Это означает, что входная строка состоит из одной строки текста. Это может быть и пустая цепочка, и в этом случае записи разделены полосой строк из пробелов или regexp, в котором записи разделяются соответствиями этому regexp во входном тексте. (См. раздел 5.1 [Как ввод делится на записи], стр. 37.) SUBSEPSUBSEP есть разделитель индексов. По умолчанию он равен ""034" и используется для разделения индексов в элементах многомерного массива. Так, выражение foo["A", "B"] фактически есть foo["A"034B"] (см. раздел 11.9 [Многомерные массивы], стр. 130). 10.2 Встроенные переменные, которые передают информациюПриведем алфавитный список переменных, которые awk устанавливает автоматически в определенных случаях для передачи информации вашей программе. Переменные, специфичные для awk, отмечены звездочкой, `*'. ARGC ARGVАргументы командной строки, доступные awk-программам, хранятся в массиве с именем ARGV. ARGC есть число присутствующих аргументов командной строки. См. раздел 14.2 [Другие аргументы командной строки], стр. 165. В отличие от большинства массивов awk, ARGV индексируется от 0 до ARGC \Gamma 1. Например: $ awk 'BEGIN - ? for (i = 0; i ! ARGC; i++) ? print ARGV[i] ? ""'& inventory-shipped BBS-list a awk a inventory-shipped a BBS-list В этом примере ARGV[0] содержит "awk", ARGV[1] содержит "inventory-shipped", а ARGV[2] содержит "BBS-list". Значение ARGC есть три, на один больше чем индекс последнего элемента в ARGV, поскольку элементы нумеруются с нуля. Имена ARGC и ARGV, также как соглашение об индексации массива от 0 до ARGC \Gamma 1, взяты из метода языка Cи для доступа к элементам командной строки. См. раздел 10.3 [Использование ARGC и ARGV], стр. 120, для сведений о том, как awk использует эти переменные. ARGIND *Индекс в ARGV текущего обрабатываемого файла. Каждый раз, когда gawk открывает новый файл с данными для обработки, он устанавливает ARGIND на индекс имени этого файла в ARGV. Когда gawk обрабатывает входные файлы, выражение `FILENAME == ARGV[ARGIND]' всегда имеет значение true. Эта переменная полезна при обработке файлов; она дает возможность узнать, как далеко программа продвинулась в списке файлов с данными и различать последовательные появления того же имени файла в командной строке. Поскольку вы можете изменять значение ARGIND в вашей awk-программе, gawk будет автоматически устанавливать ее на новое значение, когда открывается следующий файл. Эта переменная является расширением в gawk. В других реализациях awk или в gawk в режиме совместимости (см. раздел 14.1 [Параметр командной строки], стр. 161), ее нет. ENVIRONВспомогательный массив, который содержит данные об окружении. Его индексы --- имена переменных окружения. Значения есть значения некоторых переменных окружения. Например, ENVIRON["HOME"] может быть `/home/arnold'. Изменения в этом массиве не влияют на окружение, передаваемое каким-нибудь программам, которые awk может породить через перенаправление или системными средствами. (Это может быть в будущих версиях gawk.) Некоторые операционные системы могут не иметь переменных окружения. На таких системах массив ENVIRON пуст (кроме ENVIRON["AWKPATH"]). ERRNO *Если произойдет системный сбой или при перенаправлении для getline, во время чтения по getline, или во время операции close, то ERRNO будет содержать цепочку с описанием ошибки. Эта переменная представляет расширение gawk. В других реализациях awk и в gawk в режиме совместимости (см. раздел 14.1 [Параметры командной строки], стр. 161) она отсутствует. FILENAMEЭто имя файла, который awk читает в настоящее время. Если никакие файлы с данными не указаны в командной строке, awk читает из стандартного ввода и FILENAME содержит "-". FILENAME изменяется каждый раз, когда читается новый файл (см. главу 5 [Чтение входных файлов], стр. 37). Внутри правила BEGIN значение FILENAME есть "", поскольку в это время еще нет обрабатываемых входных файлов (d.c.). FNRFNR есть номер текущей записи в текущем файле. FNR увеличивается каждый раз, когда читается новая запись (см. раздел 5.8 [Явный ввод по getline], стр. 53). Она инициализируется нулем каждый раз, когда начинается новый входной файл. Некоторые ранние реализации Unix awk инициализировали FILENAME значением "-", даже если имеются файлы с данными для обработки. Такое поведение было неверным, и не надо но него полагаться в ваших программах. NFNF содержит количество полей в текущей входной записи. NF устанавливается каждый раз, когда читается новая запись, когда создается новое поле или когда меняется $0 (см. раздел 5.2 [Исследование полей], стр. 40). NRЭто количество входных записей, которые awk обработала с начала выполнения программы (см. раздел 5.1 [Как ввод разделяется на записи], стр. 37). NR изменяется каждый раз, когда читается новая запись. RLENGTHRLENGTH есть длина подцепочки, выделенной функцией соответствия (match function) (см. раздел 12.3 [Встроенные функции для действий над цепочками], стр. 137). RLENGTH устанавливается при вызове функции соответствия. Ее значение есть длина выделенной цепочки или \Gamma 1, если соответствия не обнаружено. RSTARTRSTART есть начальный индекс в символах подцепочки, найденной функцией соответствия (см. раздел 12.3 [Встроенные функции для операций над цепочками], стр. 137). RSTART устанавливается при вызове функции соответствия. Ее значение есть позиция цепочки, с которой начинается выделенная подцепочка, или 0, если соответствия нет. RT *RT устанавливается каждый раз, когда читается запись. Она содержит входной текст, который определен в RS, разделитель записей. Переменная есть расширение gawk. В других реализациях awk или в gawk в режиме совместимости (см. раздел 14.1 [Параметры командной строки], стр. 161), она не действует. ЗАМЕЧАНИЕ о NR и FNR.awk просто увеличивает обе эти переменные каждый раз при чтении записи, вместо присваивания им абсолютного значения количества прочтенных записей. Это значит, что ваша программа может изменять эти переменные, и их новые значения будут увеличиваться при чтении дальнейших записей (d.c.). Например: $ echo '1 ? 2 ? 3 ? 4' -- awk 'NR == 2 - NR = 17 "" ? - print NR ""' a 1 a 17 a 18 a 19 До того, как FNR была добавлена к языку awk (см. раздел 17.1 [Главные изменения между V7 и SVR3.1], стр. 253), многие awk-програмы использовали это свойство для определения количества записей в файле, устанавливая NR на 0 при изменении FILENAME. 10.3 Использование ARGC и ARGVВ разделе 10.2 [Встроенные переменные, которые передают информацию], стр. 117, мы видели эту программу, описывающую информацию, содержащуюся в ARGC и ARGV: $ awk 'BEGIN - ? for (i = 0; i ! ARGC; i++) ? print ARGV[i] ? ""'& inventory-shipped BBS-list a awk a inventory-shipped a BBS-list В этом примере ARGV[0] содержит "awk", ARGV[1] содержит "inventoryshipped", и ARGV[2] содержит "BBS-list". Заметим, что awk-программа не входит в ARGV. Другие специальные опции командной строки, вместе с их аргументами, также не входят. Это включает присваивания переменным, сделанным с параметром `-v' (см. раздел 14.1 [Параметры командной строки], стр. 161). Нормально присваивания переменным из командной строки рассматриваются как аргументы и показываются в массиве ARGV. $ cat showargs.awk a BEGIN - a printf "A=%d, B=%d"n", A, B a for (i = 0; i ! ARGC; i++) a printf ""tARGV[%d] = %s"n", i, ARGV[i] a "" a END - printf "A=%d, B=%d"n", A, B "" $ awk -v A=1 -f showargs.awk B=2 /dev/null a A=1, B=0 a ARGV[0] = awk a ARGV[1] = B=2 a ARGV[2] = /dev/null a A=1, B=2 Ваша программа может изменить ARGC и элементы ARGV. Каждый раз, когда awk достигает конец входного файла, она использует следующий элемент ARGV как имя следующего входного файла. Помещая туда разные цепочки, ваша программа может вмешаться в чтение файлов. Вы можете использовать "-" для представления стандартного ввода. Запоминая дополнительные элементы и продвигая ARGC, можно заставить ее читать дополнительные файлы. Если уменьшать значение ARGC, то будут исключены входные файлы из конца списка. Запоминая где-нибудь старые значения ARGC, ваша программа может трактовать исключенные аргументы как нечто иное, чем имена файлов. Чтобы исключить файл из середины списка, запишите пустую цепочку ("") в ARGV на место имени файла. Игнорировать имена файлов, замененных пустой цепочкой, есть специальная особенность awk. Можно также использовать оператор delete для удаления элементов из ARGV (см. раздел 11.6 [Оператор delete], стр. 128). Все эти действия обычно производятся из правила BEGIN, до фактического начала обработки ввода. См. раздел 16.1.4 [Разделение большого файла на части], стр. 217, и раздел 16.1.5 [Дуплицирование результата в нескольких файлах], стр. 219, как пример разных путей удаления элементов из ARGV. Следующий фрагмент обрабатывает ARGV, чтобы исследовать, а затем удалить параметры командной строки. BEGIN - for (i = 1; i ! ARGC; i++) - if (ARGV[i] == "-v") verbose = 1 else if (ARGV[i] == "-d") debug = 1 else if (ARGV[i] ~ /^-?/) - e = sprintf("%s: unrecognized option -- %c", ARGV[0], substr(ARGV[i], 1, ,1)) print e ? "/dev/stderr" "" else break delete ARGV[i] "" "" Чтобы фактически перенести параметры в awk-программу, нужно закончить awk-параметры символами `--' и затем ввести ваши параметры, подобно следующему: awk -f myprog -- -v -d file1 file2 ...Это не необходимо : пока не указано `--posix', gawk по умолчанию кладет всякий неопознанный параметр в ARGV для использования awk-программой. Как только он увидит незнакомый параметр, gawk перестает искать другие параметры, которые он иначе мог бы распознать. Предыдущий пример с gawk был бы таким: gawk -f myprog -d -v file1 file2 ...Поскольку `-d' не есть правильный параметр gawk, последующее `-v' передается awk-программе. |
<<< | Оглавление | Страницы: 10 11 | >>> |