Язык поиска и обработки шаблонов (POSIX)
gawk [-F расширенное_регулярное_выражение] [-v переменная=значение] [-W расширение_GNU...] [–] программа [аргумент]...
gawk [-F расширенное_регулярное_выражение] -f программный_файл [-v переменная=значение] [-W расширение_GNU...] [–] [аргумент]...
-
) и не является опцией.ЗОСРВ «Нейтрино»
aarch64, arm, armv7, e2k, mips, ppc, x86
Утилита gawk выполняет программы, написанные на языке программирования awk. Этот язык специально предназначен для обработки текстовой информации. Программа awk представляет собой последовательность шаблонов и соответствующих действий. Если при считывании входных данных обнаруживается совпадение с заданным шаблоном, выполняется связанное с данным шаблоном действие. Утилита gawk поставляется в составе ЗОСРВ «Нейтрино» как порт GNU awk.
Утилита gawk интерпретирует каждую строку ввода как последовательность полей. По умолчанию считается, что поле является строкой символов, не являющихся пробелами. Заменить принятый по умолчанию пробельный символ-разделитель можно с помощью встроенной переменной FS (см. раздел Переменные) или опции -F расширенное_регулярное_выражение. Утилита gawk обозначает первое поле в строке как $1
, второе поле – $2
и так далее. Обозначение $0
соответствует всей строке; настройка любого другого поля вызывает повторный анализ $0
.
Каждая строка ввода сравнивается с шаблонами; при этом длина строки ввода для функции getline (см. описание в разделе Функции) ограничена 1024 байтами.
Программы, написанные на языке awk, состоят из операторов, имеющих следующий вид:
шаблон { действие }
Можно опустить и шаблон, и действие (включая фигурные скобки). В последующих разделах этого описания, если не указано иное, игнорируются пробелы между операторами и зарезервированными словами. Внутри литеральных строк и после имени функции все пробелы являются значащими символами. При отсутствии шаблона фиксируется совпадение с любой строкой ввода, а при отсутствии действия выполняется запись совпавшей строки ввода в стандартный поток вывода.
Программа awk выполняется согласно следующей общей процедуре:
Выражения:
Выражения описывают вычислительные операции, используемые в шаблонах и действиях. Выражения в языке awk создаются на основе операторов (условных, логических и арифметических операторов, операторов присваивания, индексов и полей). В выражениях используются строковые или числовые значения в соответствии с контекстом. В следующей таблице приведены действительные выражения по группам, начиная с наивысшего приоритета.
В этой таблице выражение соответствует любому выражению. значение_слева соответствует любому объекту, которому можно присвоить значение (то есть операнду в левой части оператора присваивания).
Синтаксис | Описание |
---|---|
(выражение) | Группирование |
$выражение | Ссылка на выражение номера поля |
++значение_слева | Преинкремент значения_слева на 1 |
–значение_слева | Предекремент значения_слева на 1 |
значение_слева++ | Постинкремент значения_слева на 1 |
значение_слева– | Постдекремент значение_слева на 1 |
выражение ^ выражение | Возведение в степень |
! выражение | Логическое отрицание |
+ выражение | Унарный плюс. |
- выражение | Унарный минус. |
выражение * выражение | Умножение. |
выражение / выражение | Деление. |
выражение % выражение | Модуль целого числа. |
выражение + выражение | Сложение. |
выражение - выражение | Вычитание. |
выражение выражение | Конкатенация двух выражений |
выражение <выражение | Меньше |
выражение <= выражение | Меньше или равно |
выражение != выражение | Не равно |
выражение == выражение | Равно |
выражение > выражение | Больше |
выражение >= выражение | Больше или равно |
выражение1 ~ выражение2 | 1, если выражение1 совпадает с расширенным регулярным выражением (ERE) выражение2 |
выражение1 !~выражение2 | 1, если выражение2 не совпадает с расширенным регулярным выражением (ERE) выражение2 |
выражение in массив | 1, если существует массив[выражение] |
(индекс) in массив | Обработка многомерного массива |
выражение && выражение | Логическое И |
выражение || выражение | Логическое ИЛИ |
выражение?выражение:выражение | Условное выражение: анализируется первое выражение и, если оно ненулевое, результатом становится второе выражение; в противном случае – третье выражение |
значение_слева ^= выражение | Возвести значение_слева в степень выражение |
значение_слева %= выражение | Присвоить значение_слевавыражение операнду значение_слева |
значение_слева *= выражение | Умножить значение_слева на выражение |
значение_слева /= выражение | Разделить значение_слева на выражение |
значение_слева += выражение | Прибавить выражение к значению_слева |
значение_слева -= выражение | Вычесть выражение из значения_слева |
значение_слева = выражение | Присвоить выражение значению_слева |
Все арифметические операторы соответствуют стандарту языка C. Условное выражение возвращает строку или число (в зависимости от входных выражений). Анализируется только одно из альтернативных выражений.
Помимо описаний в предыдущей таблице, выражение также может быть числом с плавающей запятой, литеральной строкой в двойных кавычках (") или именем переменной.
Переменная или поле могут быть числом или строкой (в зависимости от текущего применения переменной или поля). Явное преобразование чисел и строк не применяются. Если выражение необходимо обработать как число, к выражению следует добавить ноль. Если выражение необходимо обработать как строку, с выражением следует объединить пустую строку (""). Переменные и поля устанавливаются оператором присваивания:
Тип операнда выражение определяет итоговый тип переменной.
Используются следующие арифметические присваивания:
+= -= *= /= %= ^= ++ --
Результатом каждого из них является числовое значение. Операндом в левой части оператора присваивания и целевым операндом в операторах инкремента и декремента могут быть следующие:
Это указывается следующей грамматикой BNF:
Действительный индекс массива состоит из одного или нескольких (разделенных запятыми) выражений; каждое выражение соответствует размерности массива. Поскольку поведение массивов awk соответствует ассоциативной памяти, индекс массива может являться любой строкой. Массивы awk фактически являются одномерными массивами, поэтому индекс многомерного массива преобразовывается в одномерный индекс. С этой целью все выражения конкатенируются с использованием в качестве разделителя значения переменной SUBSEP (см. Переменные).
Таким образом, следующие две операции с индексами являются эквивалентными:
Многомерный индекс, используемый с оператором in, следует заключить в круглые скобки. Оператор in проверяет существование определенного элемента массива, но не создает этот элемент. Однако любая другая ссылка на несуществующий элемент массива приводит к автоматическому созданию такого элемента.
Если оба операнда являются числовыми, то сравнение выполняется в числовой форме; в противном случае выполняется преобразование операндов в строки, и сравниваются строки.
В таблице выражений awk сначала сгруппированы операторы, имеющие более высокий приоритет; за ними следуют операторы с меньшим приоритетом. При вычислении выражения сначала анализируются операторы с более высоким приоритетом, а затем анализируются операторы с меньшим приоритетом. Все операторы связаны с выражением в левой части, за исключением операторов присваивания, условного оператора (?:
) и оператора возведения в степень (^
). Поскольку операция конкатенации представлена смежными выражениями (а не явным оператором), в целях корректного определения приоритета для анализа обычно требуется использовать круглые скобки.
Переменные
Переменные в программе awk используются на основе присвоения. Объявлять переменные не требуется, поскольку неинициализированная переменная всегда имеет значение пустой строки, которой соответствует нулевое числовое значение. Все переменные, включая поля, рассматриваются как строковые переменные (при условии, что они не используются в явном числовом контексте).
Переменные полей обозначаются символом $
, за которым следует число или числовое выражение.
Новая переменная поля создается путем присвоения значения этой переменной. Ссылки на несуществующие поля, т.е. поля после $(NF)
, создают пустую строку. Однако присвоение несуществующему полю (например, $(NF + 2) = 5) приводит к увеличению значения NF, созданию промежуточных полей со значением пустой строки, а также к повторному вычислению значения $0
с разделением полей значением OFS.
В следующей таблице приведены другие специальные переменные, устанавливаемые gawk.
Переменная | Значение |
---|---|
ARGC | Количество элементов в массиве ARGV |
ARGV | Массив аргументов командной строки (за исключением опций и аргумента программа) с номерами от 0 до ARGC - 1 |
FILENAME | Путевое имя текущего входного файла. |
FNR | Порядковый номер текущей записи в текущем файле |
FS | Регулярное выражение разделителя полей ввода; по умолчанию – space (пробел) |
NF | Количество полей в текущей записи |
NR | Порядковый номер текущей записи, считая с начала ввода |
OFMT | Формат вывода чисел (для оператора печати); по умолчанию – "%.6g" |
OFS | Разделитель полей вывода (для оператора печати); по умолчанию – space (пробел) |
ORS | Разделитель выходных записей (для оператора печати); по умолчанию – newline (символ новой строки) |
RLENGTH | Длина строки, совпавшей при выполнении функции сопоставления |
RS | Первый символ в строковом значении RS является разделителем входных записей; по умолчанию – newline (символ новой строки). Если RS не содержит значение, то записи разделяются пустыми строками и для разделения полей в любом случае используется newline (символ новой строки), независимо от значения FS. |
RSTART | Начальная позиция строки, совпавшей при выполнении функции сопоставления match (нумерация начинается с 1). Это значение в любом случае эквивалентно возвращаемому значению функции match. |
SUBSEP | Строка разделителя индексов в многомерных массивах; по умолчанию – \034 |
Можно изменить или добавить аргументы в ARGV и изменить ARGC. Когда обработка входного файла закончена, утилита gawk воспринимает отличный от NULL
текстовый элемент ARGV (до текущего значения ARGC - 1) как имя следующего входного файла. Следовательно, удаление значения элемента ARGV означает, что он не будет восприниматься как имя входного файла. Имя файла в виде тире (-
) означает стандартный поток ввода. Если в аргументе содержится знак равенства (=
), то такой аргумент воспринимается как присвоение, но не как аргумент файл.
Шаблоны
Структура шаблона соответствует следующей грамматике BNF:
Другими словами, шаблон представляет собой любое действительное выражение или расширенное регулярное выражение. Кроме того, шаблон может быть представлен диапазоном, заданным двумя разделенными запятой шаблонами, либо может являться одним из двух специальных шаблонов – BEGIN или END.
Специальные шаблоны BEGIN и END
Утилита gawk распознает два специальных шаблона – BEGIN и END. BEGIN однократно проверяется на совпадение, и связанное с этим шаблоном действие выполняется до считывания первой входной строки и до присвоения командной строки. END однократно проверяется на совпадение, и связанное с этим шаблоном действие выполняется после считывания последней входной строки. С этими двумя шаблонами связаны определенные действия.
BEGIN и END не объединяются с другими шаблонами. Разрешено использовать несколько шаблонов BEGIN и END. Связанные с шаблонами BEGIN и END действия выполняются в порядке, заданном в программе. В программе шаблон END может предшествовать шаблону BEGIN.
Содержимое программы | Поведение |
---|---|
Только блоки BEGIN | После выполнения последнего оператора блока BEGIN gawk не считывает входные данные и завершает работу. |
Только блоки END или только блоки BEGIN и END | Входные данные считываются перед выполнением операторов блока (блоков) END. |
Регулярные выражения
В утилите gawk используется расширенное представление регулярных выражений, за исключением предусмотренной возможности использования соглашений языка C для экранирования специальных символов в расширенных регулярных выражениях:
Управляющая последовательность | Значение |
---|---|
\b | Возврат на одну позицию |
\f | Перевод страницы |
\n | Новая строка |
\r | Возврат каретки |
\t | Табуляция |
\ddd | Восьмеричное значение, 1–3 цифры ddd |
Если используется расширенное_регулярное_выражение, то шаблон
/расширенное_регулярное_выражение/
совпадает с любой строкой ввода, в которой содержится подстрока, заданная регулярным выражением. Сравнение с регулярным выражением можно ограничить определенным полем или строкой. Для этого используется один из двух операторов сравнения регулярных выражений: ~
и !~
. Пример:
$4 ~ /расширенное_регулярное_выражение/
соответствует любой строке, в которой четвертое поле совпадает с выражением /расширенное_регулярное_выражение/.
Шаблон
$4 !~ /расширенное_регулярное_выражение/
соответствует любой строке, в которой четвертое поле не совпадает с выражением /расширенное_регулярное_выражение/.
Расширенное регулярное выражение может применяться в качестве разделителя полей. С этой целью используется опция -F расширенное_регулярное_выражение, либо выражение присваивается встроенной переменной FS. По умолчанию разделителем полей является одиночный символ пробела. Далее приведено описание поведения FS:
Диапазоны шаблонов
Диапазон шаблонов представлен двумя шаблонами, разделенными запятой. В этом случае действие выполняется для всех строк в интервале между совпадением с первым шаблоном и, включительно, совпадением со вторым шаблоном. В этой точен диапазон шаблонов может быть применен повторно, начиная со строк ввода, следующих за окончанием диапазона совпадения.
Шаблоны выражений
Шаблон выражения считается совпадающим, или истинным, если результатом вычисления выражения является числовое значение, отличное от нуля. В противном случае шаблон считается ложным.
Действия
Действие – это последовательность операторов. Далее приведен список используемых операторов. В этом списке необязательные элементы заключены в квадратные скобки [ ]
. Ключевые слова выделены моноширинным шрифтом.
Любой отдельный оператор может быть заменен списком операторов, заключенным в фигурные скобки {}
. Операторы в списке операторов разделяются символом newline (новая строка) или символом "точка с запятой". Символ #
в любом месте в строке программы (в символьных строках или расширенных регулярных выражениях) обозначает начало комментария, который продолжается до конца этой строки программы.
Операторы завершаются символом "точка с запятой" или newline (новая строка). Длинный оператор можно разместить в нескольких строках; в этом случае каждая частичная строка должна заканчиваться символом обратной косой черты. Символам newline (новая строка) без обратной косой черты могут предшествовать следующие элементы:
Пример:
Строковые константы заключаются в двойные кавычки ("строка"). Строковое выражение создается путем конкатенации констант, переменных, имен полей, элементов массива, функций и других выражений.
Анализируется выражение, используемое в качестве условного выражения в операторе if, и, если получен ненулевой и непустой результат, выполняется следующий оператор. Иначе, если присутствует ключевое слово else, выполняется оператор, следующий за ключевым словом else.
Операторы while, do...while, for, break и continue соответствуют стандарту языка C, за исключением того, что оператор for ( переменная in массив ) по порядку итеративно присваивает каждое значение индекс операнда массив операнду переменная. Эта форма оператора for используется для обработки всех элементов массива. Порядок обработки не задается.
Язык awk поддерживает обработку массивов, используемых для хранения чисел или строк. Объявлять массивы не требуется, их размеры изменяются динамически. Индексы (идентификаторы элементов) представляют собой строки, определяющие в качестве типа ассоциативный массив. Индексы сами по себе не могут составлять массивы.
Оператор delete удаляет отдельный элемент массива. Приведенный ниже код удаляет весь массив:
for (индекс in массив) delete массив[индекс]
Оператор next прекращает обработку текущей строки ввода.
Оператор exit вызывает все действия END в том порядке, в котором они приведены в исходном коде программы. Оператор next внутри END также завершает выполнение программы и дополнительно может установить статус завершения утилиты.
Операторы вывода
По умолчанию операторы print и printf передают выходные данные в стандартный поток вывода. Выходные данные записываются в местоположение, заданное переменной выражение_перенаправления (при наличии такой переменной):
В любом случае анализируется выражение, и полученная строка применяется в качестве полного путевого имени, по которому должна быть выполнена запись (при использовании > или >>), либо в качестве исполняемой команды (при использовании |). С помощью первых двух форм оператора, если файл с этим именем в данный момент не открыт: файл создается (при необходимости), открывается и усекается с помощью первой формы. Затем выходные данные добавляются в этот файл. Последующие вызовы анализа выражения, в результате которых формируется то же самое имя, просто добавляют выходные данные в этот файл. Файл остается открытым до тех пор, пока он не будет закрыт.
Третья форма оператора записывает выходные данные в поток, совместимый с popen(). Если в настоящий момент открытый поток отсутствует, то создается поток с тем же самым именем команды. Созданный поток совместим с функцией popen(), вызываемой с использованием режима w. При выполнении последующих вызовов выходные данные записываются в существующий поток (при условии, что при выполнении этих вызовов результатом анализа выражения будет имя команды, совпадающее с именем потока, открытого в настоящий момент). Поток закрывается (как при вызове функции pclose()), если результатом анализа выражения будет имя, совпадающее с именем команды.
Оператор print записывает значение каждого аргумента выражения в указанный поток вывода. Для разделения значений используется текущий разделитель полей вывода (см. OFS в таблице переменных gawk). Запись завершается разделителем выходных записей (см. ORS в той же таблице). Строковые выражения записываются "как есть". Числовые выражения записываются так, как если бы они были обработаны командой printf с использованием формата, являющегося строковым значением переменной OFMT. Список_выражений представляет собой список выражений, разделенных запятыми. Пустой список_выражений соответствует целой строке ввода ($0
).
printf выводит выражения согласно заданному формату. Необходимо указать аргумент, определяющий формат. Все остальные аргументы в списке_выражений являются необязательными. Строковое значение выражения формат интерпретируется так же, как в C-функции printf() (см. ниже). В строке формат спецификация формата начинается с одиночного символа %
и может дополнительно содержать три модификатора:
Модификатор | Значение |
---|---|
- | Выровнять выражение по левому краю поля |
ширина | Заполнить поле влево до этой ширины; начальный нуль 0 означает заполнение нулями |
.точность | Задать максимальную ширину строки или количество цифр справа от десятичной запятой |
Спецификация формата завершается любым другим символом. Для каждой спецификации формата, использующей некоторый аргумент, следующий аргумент из списка список_выражений анализируется и преобразовывается в значение соответствующего типа (строка, целое число, число с плавающей запятой). print и printf могут выводить не менее 1024 байт.
В утилите gawk используются следующие символы определения формата:
Символ | Интерпретация |
---|---|
c | Если аргумент является числом, вывести символ; если аргумент является строкой, вывести только первый символ. |
d | Десятичное целое число |
e | Экспоненциальное представление: [-]d.ddddddE[+-]dd |
f | Представление с плавающей запятой: [-]ddd.dddddd |
g | Укороченное представление e или f (с подавлением незначащих нулей) |
o | Восьмеричное число без знака |
s | Строка |
x | Шестнадцатеричное число без знака |
% | Вывести % (аргумент не используется) |
Функции:
В языке awk реализовано множество встроенных функций: арифметические и строковые функции, функции ввода-вывода, функции общего назначения.
Арифметические функции:
Арифметические функции соответствуют стандарту языка C (за исключением функции int).
Строковые функции:
$0
или в строке, заданной аргументом целевая_строка (если этот аргумент задан). $0
. -1
, если совпадение не обнаружено. $0
). Для всех вышеприведенных функций, в которых присутствует параметр расширенное_регулярное_выражение, в качестве регулярного выражения используется шаблон или выражение, имеющее строковое значение.
Входные/выходные и общие функции:
$0
и NF; если переменная задана, устанавливается переменная. $0
на следующую входную запись в текущем входном файле. Эта форма getline устанавливает переменные NF, NR и FNR. $0
на следующую запись в файле с путевым именем, определяемым выражением. Эта форма getline устанавливает переменную NF. Все формы getline возвращают 1 при успешном выполнении ввода, 0 при достижении конца файла и -1 в случае ошибки.
Определяемые пользователем функции
Язык awk поддерживает пользовательские функции. Эти функции можно определить следующим образом (в позиции шаблона в операторе типа "шаблон-действие"):
function имя(аргументы,...) {операторы}
Ссылка на функцию может находиться в любом месте в программе awk. В частности, вызов функции может предшествовать определению функции. Функция действует глобально.
Аргументы функции передаются по значению (если они являются скалярными величинами) и по ссылке (если они являются именами массивов). Имена аргументов являются локальными именами для функции; все другие имена переменных являются глобальными именами. Количество параметров в определении функции может не совпадать с количеством параметров в вызове функции. Избыточные формальные параметры могут использоваться в качестве локальных переменных. Если количество аргументов в вызове функции меньше их количества в определении функции, излишние принимаемые параметры не инициализируются.
Следует учитывать, что в вызове функции должны отсутствовать пробельные символы между именем функции и открывающей круглой скобкой. Вызовы функции могут быть вложенными и рекурсивными. Для возврата значения допускается использовать оператор return.
В определении функции можно вводить дополнительные символы новой строки (newline) перед открывающей фигурной скобкой и после закрывающей фигурной скобки. Определения функций могут располагаться в любом месте в программе, где допускается использование оператора типа "шаблон-действие". В вызове функции запрещено вводить пробельные символы между именем функции и открывающей круглой скобкой, с которой начинается список параметров функции.
Примеры программ awk
Следует отметить, что далее приведены только примеры программ awk, но не полные командные строки.
Запись в стандартный поток вывода всех строк ввода, в которых поле 3 больше 5:
$3 > 5
Вывод каждой десятой строки:
(NR % 10) == 0
Вывод всех строк, подстрока в которых совпадает с регулярным выражением:
/(G|D) (2[0-9][[:alpha:]]*)/
Вывод предпоследнего поля и последнего поля каждой строки; с разделением полей двоеточием:
Вывод номера строки и количества полей в каждой строке. Объедиение трех строк, представляющих номер строки, двоеточия и количества полей, и запись результирующей строки в стандартный поток вывода:
Вывод строки длиной свыше 72 символов.
length $0 > 72
Вывод первых двух полей в обратном порядке, с разделителем OFS:
Аналогична предыдущей, но с разделением полей ввода запятой, или символами пробела (space) и табуляции (tab), или комбинацией всех этих символов:
BEGIN {FS = ",[ \t]*|[ \t]+" } { print $2, $1 }
Сложение значений в первом столбце и вывод суммы и среднего значения:
END {print "sum is ", s, " average is", s/NR}
Вывод полей в обратном порядке и по одному полю в каждой строке (т.е использование нескольких строк вывода для каждой строки ввода):
Вывод всех строк в интервале между обнаруженными символьными строками start и stop:
/start/, /stop/
Вывод всех строк, первое поле в которых отличается от первого поля в предыдущей строке:
$1 != prev { print; prev = $1 }
Имитация эхо-вывода:
BEGIN { for (i = 1; i < ARGC; ++i) printf "%s%s", ARGV[i], i==ARGC-1?"\n":" " }
Если существует файл с именем myfile, содержащий заголовки страниц в виде
Page #
и существует файл с именем program, содержащий
/Page/{ $2 = n++; } { print }
то в результате ввода командной строки
gawk -f program n=5 myfile
будет выведен файл myfile, заполненный номерами страниц, начиная с 5.
Вывод файла myfile, содержащего ссылки на страницы, заполнение его номерами страниц, начиная с 5:
gawk '/Page/{ $2=n++; } { print }' n=5 myfile
По умолчанию входные файлы являются текстовыми файлами, чтение которых выполняется по порядку. Для перехода от принятой по умолчанию процедуры обработки файлов к обработке под управлением программы можно изменить переменную ARGV или переменную ARGC.
Особенности выходных файлов зависят от программы awk.
Базовые подсистемы ЗОСРВ «Нейтрино», POSIX
ЗОСРВ
«Нейтрино»
редакции 2020
утилита обновлена до версии 5.0.61
Предыдущий раздел: Утилиты