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

Arnold D. Robbins
перевод Балуева А. Н.

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.

FS

FS представляет входной разделитель полей (см. раздел 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.)

SUBSEP

SUBSEP есть разделитель индексов. По умолчанию он равен ""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.).

FNR

FNR есть номер текущей записи в текущем файле. FNR увеличивается каждый раз, когда читается новая запись (см. раздел 5.8 [Явный ввод по getline], стр. 53). Она инициализируется нулем каждый раз, когда начинается новый входной файл.

Некоторые ранние реализации Unix awk инициализировали FILENAME значением "-", даже если имеются файлы с данными для обработки. Такое поведение было неверным, и не надо но него полагаться в ваших программах.

NF

NF содержит количество полей в текущей входной записи. NF устанавливается каждый раз, когда читается новая запись, когда создается новое поле или когда меняется $0 (см. раздел 5.2 [Исследование полей], стр. 40).

NR

Это количество входных записей, которые awk обработала с начала выполнения программы (см. раздел 5.1 [Как ввод разделяется на записи], стр. 37). NR изменяется каждый раз, когда читается новая запись.

RLENGTH

RLENGTH есть длина подцепочки, выделенной функцией соответствия (match function) (см. раздел 12.3 [Встроенные функции для действий над цепочками], стр. 137). RLENGTH устанавливается при вызове функции соответствия. Ее значение есть длина выделенной цепочки или \Gamma 1, если соответствия не обнаружено.

RSTART

RSTART есть начальный индекс в символах подцепочки, найденной функцией соответствия (см. раздел 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 >>>