AWK(1)

Документ справочника MAN

СИНТАКСИС

/usr/bin/awk [ -f progfile ] [ -Fc ] [ 'prog' ] [ filename...]

/usr/bin/nawk  [ -F ERE ]  [ -v var=value ...  ]  'prog' -f progfile ...  [ filename ... ]

ОПИСАНИЕ

Awk - язык разбора и обработки текстовых файлов по заданным шаблонам. Nawk - расширенная версия awk.

Awk сканирует каждый файл из списка входных файлов filename в поиске записей, соответствующих какому-либо из шаблонов, приведенных в программе prog. Текст программы prog должен быть заключен в одинарные кавычки для полного экранирования содержимого программы от шелла. Для каждого шаблона в программе prog может быть указано связанное с ним действие, которое выполняется, когда какая-либо запись из входных файлов filename соответствует шаблону. Набор выражений типа шаблон-действие и составляет собой программу prog; эта программа может быть приведена непосредственно в командной строке при вызове awk или содержаться в файле progfile, указанном с помощью опции

-f progfile.

По умолчанию записью во входном файле считается строка (набор символов до символа перевода строки).

Входные файлы filename читаются в порядке их указания в командной строке, если входные файлы не указаны, читается стандартный ввод. Файл с именем '-' обозначает стандартный ввод.

Параметры и имена входных файлов

Любое имя входного файла в командной строке вызова awk, имеющее форму нечто=некое_значение (где нечто начинается с буквы или символа подчеркивания и состоит из букв, цифр и символов подчеркивания) рассматривается как оператор присвоения, а не как имя входного файла, и исполняется непосредственно перед открытием следующего файла из списка.

Переменные (нечто), назначаемые таким образом, передаются в программу awk, однако они не доступны внутри секции BEGIN и получают указанные значения (некое_значение) после того, как будут прочитаны и обработаны все входные файлы, указанные в командной строке вызова awk перед параметром нечто=некое_значение.

Если такое присвоение находится после последнего файла из списка входных файлов, то оно будет выполнено после того, как будет прочитан последний входной файл, но перед выполнением секции END, если таковая имеется.

Программа nawk предлагает также другой способ инициализации переменных вне текста программы - с помощью ключа -v в командной строке nawk. В этом случае переменная получает значение перед началом работы программы, то есть доступна внутри секции BEGIN, если таковая имеется. Несколько присвоений могут следовать за одним ключом -v.

Присвоение переменным awk значений извне awk-программы может понадобиться, если awk-переменная должна иметь значение какой-либо переменной окружения и или результата подстановки команды, так как изнутри awk-программы доступа к этим данным нет. См. пример 9 в конце документа.

ОПЦИИ

-f  progfile
программа для awk считывается из файла progfile. Для nawk можно указывать несколько файлов, при это программа будет сформирована путем конкатенации этих файлов в порядке их указания.

-F c
использовать символ c в качестве разделителя полей (FS). См. ниже описание FS. Программа nawk позволяет указывать в опции -F не только символы, но и регулярные выражения.

-v var=value ...
инициализация значений переменных (только nawk), описание см. выше.

ПРИМЕНЕНИЕ

Входные записи

Содержимое входного файла интерпретируется как последовательность записей, каждая из которых состоит из полей. По умолчанию записи разделяются сиволами перевода строки, поля - одним или более пробельных символов (пробелы и табуляции). Эти значения могут быть изменены путем модификации встроенных переменных соответственно RS и FS.

Awk последовательно считывает записи из входного файла. Каждая очередная запись проверяется на соответствие шаблонам во всех выражениях вида шаблон-действие, последовательность которых и составляет программу. Проверка выполняется в порядке расположения выражений в программе. В каждом случае соответствия выполняется связанное со сработавшим шаблоном действие. Действие выполняется до проверки следующего шаблона. После проверки последнего шаблона программы, awk считывает из входного файла очередную запись и цикл повторяется.

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

Поля каждой разбираемой в данный момент записи сохраняются во встроенных переменных $1, $2, ...; $0 относится ко всей записи целиком.

Выражения шаблон-действие

Выражение шаблон-действие, являющееся структурной единицей awk-программы, имеет вид:


          шаблон { действие }

Выражения шаблон-действие разделяются переводом строки или точкой с запятой.

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

Шаблоны

Шаблоны являются Булевыми комбинациями ( !, ||, && и скобки) относительных и регулярных выражений.

Относительным выражением называется любое из следующих выражений:

          выражение операция_отношения выражение
          выражение операция_соответствия регулярное_выражение
где операция_отношения - любая из шести операций отношения языка Си, а операция_соответствия - либо ~ ("содержит"), либо !~ ("не содержит"). Выражением является арифметическое выражение, относительное выражение, или специальное выражение вида

          переменная in массив

(переменная является существующим индексом элемента массива), или Булева комбинация вышеуказанных выражений.

Регулярные выражения определены в egrep(1). В шаблонах они должны быть окружены слэшами (/). Отдельно стоящее в шаблоне регулярное выражение применяется ко всей записи. Регулярные выражения также могут находиться внутри относительных выражений.

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

Примеры шаблонов (встроенная переменная NF сожержит число полей текущей записи, соответственно $NF - значение последнего поля):

NF==7 && /^Name:/
"в записи 7 полей И запись начинается с 'Name:'"

$1>0 || $(NF-1) ~ /[0-9]+/
"первое поле записи - положительное число ИЛИ предпоследнее поле состоит только из цифр"

/^[Bb]egin/,/^[Ee]nd/
"все записи от записи, начинающейся со слова 'Begin' или 'begin', до записи, начинающейся со слова 'End' или 'end', влючительно"

Для выполнения инициализационных (перед считыванием первой записи первого входного файла) и завершающих (после обработки последней записи последнего входного файла) действий используются специальные шаблоны BEGIN и END соответственно. Эти ключевые слова не могут входить ни в какие другие шаблоны.

Nawk: если в программе имеется несколько шаблонов BEGIN или END - например, если программа образована конкатенацией нескольких программ - то действия этих шаблонов выполняются в порядке появления их в тексте программы.

Встроенные переменные

FILENAME
имя текущего входного файла

FS
символ-разделитель полей во входных строках (в nawk - регулярное выражение), по умолчанию пробел или табуляция. Значение FS может быть изменено как с помощью присвоения внутри программы, так и опцией -F при вызове awk

NF
число полей в текущей записи

NR
порядковый номер текущей записи среди всех входных записей

OFMT
формат вывода чисел (по умолчанию %.6g)

OFS
разделитель полей при выводе (по умолчанию пробел)

ORS
разделитель записей при выводе (по умолчанию перевод строки)

RS
разделитель записей на входе, по умолчанию перевод строки

Действия

Действие - это последовательность операторов. Список возможных операторов приведен ниже.

Пояснения:

for ( переменная in массив ) оператор
определяет цикл по всем элементам массива, причем переменная последовательно принимает значения индексов всех элементов этого массива;
next
прекратить разбор текущей записи, перейти к разбору следующей записи (начиная с первого шаблона);
exit [выражение]
проигнорировать оставшиеся входные записи, выполнить действие шаблона END, если таковой имеется, и прекратить работу программы; состоянию выхода (exit status) присвоить значение выражения

Остальные операторы интепретируются как в языке Си.

Несколько операторов могут быть объединены в один путем помещения их внутрь фигурных скобок.

Оператор завершается точкой с запятой, переводом строки или правой фигурной скобкой. Распространенная ошибка:

if (a == b) 
{
  a++;
  print b;
}
здесь оператор if заканчивается переводом строки, следующим за '(a==b)', и последующая группа операторов в фигурных скобках не имеет к if никакого отношения и выполняется всегда. Правильно писать, например:
if (a == b) {
  a++;
  print b;
}

Пустой список_выражений означает "вся запись". Выражения воспринимаются как строковые или численные судя по контексту и строятся с использованием арифметических операций

+ - * / % ^
и конкатенации (объединения) строк, обозначаемой с помощью пробела. (Пример конкатенации:
a="world!"
b="Hello, " a
переменная b приобретает значение "Hello, wolrd!")

В выражениях также могут быть использованы операции языка Си:

++  --  += -= *= /= %= ^= > >= < <= == != ?:

Переменные могут быть скалярами (пременная, содержащая одно числовое или строковое значение) или элементами массивов (обозначаются, например, x[i]).

Тип скалярной переменной (число это или строка) определяется по контексту производимых с переменной действий. Явного преобразования между числами и строками не предусмотрено. Чтобы выражение принудительно интерпретировалось как число, прибавьте к нему 0. Чтобы выражение принудительно интерпретировалось как строка, объедините его с пустой строкой ("").

Переменные не описываются и создаются при их упоминании, при этом они инициализируются пустой строкой или нулем, если явно не задано иное. Начальные значения переменных в виде переменная=значение могут задаваться в командной строке при вызове awk (см. выше "Параметры и имена входных файлов").

Индексы массивов - не обязательно числа, они могут быть и строковыми; что позволяет создавать ассоциативные массивы (хэши). Для перебора индексов таких массивов в цикле используйте оператор "for (var in array)".

Строковые константы заключаются в двойные кавычки (""), при этом в строках распознаются спецсимволы языка Си (\n,\t и т.п.).

Оператор print выводит свои аргументы в стандартный вывод, или в файл, если указано перенаправление '>выражение' (значение выражения вычисляется и становится именем файла), или в программный конвейер, если оператор завершается перенаправлением '|команда' . Вывод оператора print заканчивается разделителем записей при выводе (ORS), а каждый элемент вывода (аргумент оператора), отделяется от следующего разделителем полей при выводе (OFS).

Оператор printf форматирует для вывода список_выражений в соответствии с указанным форматом аналогично тому, как это делает соответствующая функция языка Си.

Встроенные функции

Арифметические функции

cos(х)
возвращает косинус х.

exp(х)
возвращает экспоненту х.

int(s)
возвращает целую часть s как целое значение. Если s не указано (например: '{ int }'), используется $0 (вся текущая запись).

log(x)
возвращает натуральный логарифм х.

sin(х)
возвращает синус х.

sqrt(х)
возвращает квадратный корень из х.

Строковые функции

index(s, t)
возвращает позицию в строке s, начиная с которой впервые появляется подстрока t, или 0, если такая подстрока отсутствует. Первый символ строки находится на позиции 1.

length(s)
возвращает длину своего аргумента s, интепретируемого в данный момент как строка, или всей входной строки, если аргумент не задан (например, '{ length }').

match(s, re)
возвращает позицию в строке s, начиная с которой находится регулярное выражение re, или 0, если регулярное выражение в строке отсутствует. Первый символ строки находится на позиции 1.

split(s, a, fs)
разбивает строку s на массив из элементов a[1], a[2], ..., a[n], и возвращает n. Разделителем элементов в строке служит регулярное выражение fs, или текущий разделитель входных полей FS, если fs не задано.

sprintf(fmt, expr, expr,...)
форматирует выражения expr в соответствии с форматом fmt (аналогично формату в функции printf языка Си) и возвращает получившуюся строку.

substr(s, m, n)
возвращает n-символьную подстроку строки s, которая начинается с позиции m. Первый символ строки s находится на позиции 1.

Имеется также встроенная функция ввода-вывода:

getline
устанавливает $0 равным следующей записи из текущего входного файла; возвращает 1 в случае успешного ввода строки, 0 - конец файла, -1 - ошибка.

ПРИМЕРЫ

Ниже приведены примеры awk-программ.

1. Вывод строк с длиной больше 72:

          length > 72

2. Вывод первых двух полей каждой строки в обратном порядке:

          { print $2, $1 }

3. Сложить значения в пятой колонке, вывести сумму и среднее:

               { s += $5 }
          END  { print "sum is", s, ", average is", s/NR }
Пример использования:

ls -l | awk '
               { s += $5 }
          END  { print "sum is", s, ", average is", s/NR } ' -
4.

Вывести все поля каждой строки в обратном порядке:

          { for (i = NF; i > 0; --i) print $i }

Вывести поля в обратном порядке для строк, первое поле которых - слово "reverse":

   $1=="reverse"  { for (i = NF; i > 0; --i) print $i }
5.

Вывести все строки между парами "start" - "stop":

          /start/, /stop/
6.

Вывести все строки, в которых первое поле отличается от первого поля предыдущей строки:

          $1 != prev { print; prev = $1 }
7. Вывести первую строку каждого абзаца (абзацы разделяются пустой сторокой):

        BEGIN { FS="\n" ; RS="" }
              {print $1 }
8. Вывести имена, идентификаторы и домашние каталоги пользователей из файла /etc/passwd, разделяя их табуляциями (в файле /etc/passwd поля разделяются двоеточиями):

awk ' BEGIN { FS=":" ; OFS="\t" }
            { print $1, $2, $6  }
' /etc/passwd
9. Вывести файл input.txt, автоматически вставляя номера рисунков после слова "Fig." (слово находится в начале строки). Начальный номер рисунка задается переменной окружения FIGNUMBER:

awk '
      /^Fig\./ { $2 = n++; }
               { print }
' n=$FIGNUMBER input.txt
или

nawk -v  n=$FIGNUMBER '
      /^Fig\./ { $2 = n++; }
               { print }
' input.txt

Если начальный номер рисунка вычисляется программой 'getfignumber', которая выводит его на стандартный вывод:

nawk -v  n=`getfignumber` '
      /^Fig\./ { $2 = n++; }
               { print }
' input.txt

СМ. ТАКЖЕ

egrep(1), grep(1), nawk(1), sed(1), printf(3S), environ(5)

ПРИМЕЧАНИЯ

Пробел во входной строке не сохраняется при выводе, если аргументами вывода являются поля ($NNN).




(С) Петлинский В.П., перевод и редактирование,