awk Язык поиска и обработки шаблонов Тип файла: команда usage: awk [-v var=value] [-f progfile | 'prog'] [file ...] Комментарии СИНТАКСИС awk [-f файл_программы | 'программа'] [-F разделитель] [-v переменная=значение] [файл ...] ОПИСАНИЕ awk сканирует каждый входной файл в поисках строк, соответствующих любому из набора шаблонов (образцов), указанных в программе. Строку программы необходимо брать в одиночные кавычки ('), чтобы защитить ее от обработки командным интерпретатором. Шаблоны представляют собой произвольную логическую комбинацию расширенных регулярных выражений (см. grep(1)) и относительных выражений (relational expressions). С каждым шаблоном в программе может быть связано действие, выполняемое, когда строка файла сопоставляется с шаблоном. Набор пар шаблон-действие можно вводить непосредственно как программу, а можно и в файле, который указывается с помощью опции -f файл_программы. Входные файлы читаются последовательно; если файлы не указаны, читается стандартный входной поток. Имя файла - обозначает стандартный входной поток. awk обрабатывает символы дополнительного набора в парах шаблон-действие и комментариях, а также распознает символы дополнительного набора в качестве разделителей полей (см. ниже) в соответствии с локалью, заданной в переменной среды LC_CTYPE (см. LANG в environ(5)). В регулярных выражениях поиски шаблонов выполняются над символами, а не над байтами, как описано на странице справочного руководства grep(1). Каждая входная строка сопоставляется с шаблоном каждой пары шаблон-действие; для каждого сопоставившегося шаблона выполняется соответствующее действие. Любой аргумент вида переменная=значение рассматривается как присваивание, а не как имя файла, и выполняется в момент, когда он должен был бы открываться, если бы представлял собой имя файла. Опция -v, за которой идет конструкция переменная=значение, представляет собой присваивание, которое должно быть сделано перед выполнением программы; можно задавать любое количество опций -v. Входная строка обычно состоит из полей, разделенных пробельными символами. (Это умолчательное предположение можно изменить с помощью встроенной переменной FS или опции -Fразделитель.) Поля обозначаются $1, $2, ...; $0 ссылается на всю строку в целом. Пара шаблон-действие имеет вид: шаблон { действие } Шаблон или действие можно не указывать. Если для шаблона не задано действие, соответствующая строка просто выдается. Если для действия не указан шаблон, это действие выполняется для каждой входной строки. Пары шаблон- действие разделяются переводами строк или точками с запятыми. Как уже упоминалось, шаблоны представляют собой произвольные логические комбинации (с использованием !, ||, && и круглых скобок) относительных выражений и расширенных регулярных выражений. Относительным называется любое из следующих выражений: выражение оператор_отношения выражение выражение оператор_сопоставления регулярное_выражение выражение in имя_массива (выражение, выражение, ... ) in имя_массива где оператор_отношения представляет собой один из шести операторов отношения в языке C, а оператор_сопоставления - это либо ~ (содержит), либо !~ (не содержит). Выражением может быть арифметическое выражение, относительное выражение, специальное выражение переменная in массив или их логическая комбинация. В шаблонах расширенные регулярные выражения необходимо заключать в косые черты (/). Отдельное регулярное выражение в шаблоне применяется ко всей строке. Расширенные регулярные выражения могут также использоваться в относительных выражениях. Шаблон может состоять из двух шаблонов через запятую; в этом случае действие выполняется для всех строк между соответствующей первому шаблону и следующей соответствующей второму шаблону. Специальные шаблоны BEGIN и END можно использовать для получения управления перед чтением первой входной строки и после прочтения последней входной строки, соответственно. Эти ключевые слова нельзя сочетать с другими шаблонами. Для задания разделителя полей можно использовать расширенное регулярное выражение, используя опцию -Fразделитель или присваивая выражение встроенной переменной FS. По умолчанию, начальные пробелы в строках игнорируются, а поля разделяются произвольным количеством пробелов и/или символов табуляции. Однако, если переменной FS присвоено значение, начальные пробелы не будут игнорироваться. Имеются и другие встроенные переменные: ARGC количество аргументов командной строки ARGV массив аргументов командной строки ENVIRON массив переменных среды; в качестве индексов используются имена переменных FILENAME имя текущего входного файла FNR порядковый номер текущей записи в текущем файле FS регулярное выражение, задающее разделитель входных полей (по умолчанию - пробелы и символы табуляции) NF количество полей в текущей записи NR порядковый номер текущей записи OFMT выходной формат для чисел (по умолчанию - %.6g) OFS разделитель выходных полей (по умолчанию - пробел) ORS разделитель выходных записей (по умолчанию - новая строка) RS разделитель входных записей (по умолчанию - новая строка) SUBSEP разделитель нескольких индексов (по умолчанию - символ с кодом 034) Разделители, задаваемые с помощью опции -F или переменных OFS, ORS и FS, могут содержать символы дополнительного набора. Действие представляет собой последовательность операторов. Имеются следующие операторы: if ( выражение ) оператор [else оператор] while ( выражение ) оператор do оператор while ( выражение ) for ( выражение ; выражение ; выражение ) оператор for ( переменная in массив ) оператор delete массив[индекс] # удаление элемента массива break continue { [оператор] ... } выражение # обычно, переменная = выражение print [список_выражений] [>выражение] printf формат [, список_выражений] [>выражение] next # пропустить оставшиеся шаблоны для этой строки exit [выражение] # пропустить остальные входные # строки; выражение задает # код возврата return [выражение] Операторы заканчиваются точкой с запятой, новой строкой или закрывающей фигурной скобкой. Пустой список_выражений означает всю входную строку. Выражения будут иметь строковые или числовые значения, в зависимости от строения, и строятся с использованием операторов +, -, *, /, %, ^ и конкатенации (выполняемой при записи подряд). В выражениях также можно использовать операторы ++, --, +=, -=, *=, /=, %=, ^=, >, >=, <, <=, ==, !=, ?:. Переменные могут быть скалярами, элементами массивов (записывается как x[i]) или полями. Переменные инициализируются пустыми строками или нулями. Индексами массивов могут быть любые строки, не обязательно только числовые; это позволяет реализовать ассоциативную память. Допускается использование нескольких индексов, например [i,j,k]; составные элементы конкатенируются, разделяясь значением встроенной переменной SUBSEP. Строковые константы берутся в двойные кавычки (""), причем в них распознаются стандартные управляющие символы языка C. Оператор print выдает аргументы в стандартный выходной поток или в файл, если указано > выражение, или по конвейеру, если указано |команда. Аргументы разделяются текущим разделителем выходных полей и завершаются разделителем выходных записей. Оператор printf форматирует свой список_выражений в соответствии с указанным форматом (см. fprintf(3S)). Встроенная функция close(выражение) закрывает указанный файл или поток, задаваемый выражением. Математические функции atan2, cos, exp, log, sin, sqrt являются встроенными. Другие встроенные функции включают: gsub(for, repl, in) работает аналогично sub (см. ниже), но заменяет последовательные вхождения регулярного выражения (как команда глобальной подстановки в ed) index(s, t) возвращает позицию первого вхождения строки t в строке s, или 0, если такой подстроки в s нет int усекает до целого значения length(s) возвращает длину в байтах аргумента, рассматриваемого как строка, или длину входной строки, если аргумент не указан match(s, re) возвращает позицию вхождения регулярного выражения re в строке s, или 0, если такого выражения в строке нет. Переменная RSTART устанавливается в начальную позицию соответствующей подстроки (которая совпадает с возвращаемым значением), а переменная RLENGTH устанавливается равной длине соответствующей подстроки rand случайное число в диапазоне (0, 1). split(s, a, fs) разбивает строку s на массив элементов a[1], a[2],... a[n] и возвращает их количество - n. В качестве разделителя используется регулярное выражение fs или разделитель полей FS, если аргумент fs не задан. srand устанавливает базовое значение (seed) для функции rand sprintf(fmt, expr, expr,...) форматирует выражения в соответствии с форматом fprintf(3S), задаваемым аргументом fmt, и возвращает получившуюся в результате строку. sub(for, repl, in) подставляет строку repl вместо первого вхождения регулярного выражения for в строку in и возвращает количество подстановок. Если строка in не указана, awk выполняет подстановки в текущей записи ($0). substr(s, m, n) возвращает n-символьную подстроку строки s, начиная с позиции m. Поддерживаются также следующие встроенные функции ввода/вывода: close(имя_файла) закрывает файл или поток с именем имя_файла. cmd | getline направляет выходной поток команды cmd функции getline; каждый последующий вызов getline возвращает следующую строку из выходного потока cmd. getline устанавливает $0 в следующую входную запись из текущего входного файла. getline <файл устанавливает $0 в следующую запись из файла. getline x устанавливает значение переменной x. getline x <файл устанавливает x значение следующей записи из файла. system(команда) выполняет команду и возвращает ее код возврата. Все формы функции getline возвращают 1 в случае успешного чтения, 0 - в случае конца файла и -1 в случае ошибки. awk также позволяет создавать функции, определяемые пользователем. Такие функции можно определять (в позиции шаблона пары шаблон-действие) следующим образом function имя(аргументы,...) { операторы } или func имя(аргументы,...) { операторы } Аргументы функции передаются по значению, если являются скалярами, и по ссылке, если представляют собой имена массивов. Имена аргументов локальны по отношению к функции; все остальные имена переменных - глобальные. Вызовы функций могут быть вложенными, а сами функции - рекурсивными. Оператор return можно использовать для возвращения значения из функции. ПРИМЕРЫ Выдать строки длиннее 72 символов: length > 72 Выдать первые два поля в обратном порядке: { print $2, $1 } То же, но входные поля разделены запятой и/или пробелами и символами табуляции: BEGIN { FS = ",[ \t]*|[ \t]+" } { print $2, $1 } Просуммировать первый столбец, выдать сумму и среднее значение: { s += $1 } END { print "sum is", s, " average is", s/NR } Выдать поля в обратном порядке: { for (i = NF; i > 0; --i) print $i } Выдать все строки между парами шаблонов start/stop: /start/, /stop/ Выдать все строки, первое поле в которых отличается от первого поля предыдущей строки: $1 != prev { print; prev = $1 } Имитировать команду echo(1): BEGIN { for (i = 1; i < ARGC; i++) printf "%s", ARGV[i] printf "\n" exit } Выдать файл, заполняя номера страниц, начиная с 5: /Page/ { $2 = n++; } { print } Если эта программа находится в файле по имени prog, следующая команда распечатает файл input, пронумеровав его страницы начиная с 5: awk -f prog n=5 input. ФАЙЛЫ /usr/lib/locale/локаль/LC_MESSAGES/uxawk файл сообщений для текущего языка (См. LANG в environ(5).) ПРИМЕЧАНИЯ Входные пробелы не сохраняются в выходном потоке, если задействованы поля. Нет явного преобразования чисел в строки и наоборот. Чтобы выражение рассматривалось как числовое, добавьте к нему 0; чтобы оно рассматривалось как строковое, конкатенируйте его с пустой строкой (""). -------------- Синтаксис команды awk Уилита читает документ по одной строке за раз, выполняет указанные вами действия и выводит результат на стандартный вывод. Одна из самых частых задач, для которых используется awk - это выборка одной из колонок. Все параметры awk находятся в кавычках, а действие, которое надо выполнить - в фигурных скобках. Синтаксис: $ awk опции 'условие {действие}' $ awk опции 'условие {действие} условие {действие}' С помощью действия можно выполнять преобразования с обрабатываемой строкой. Опции утилиты: -F, --field-separator - разделитель полей, используется для разбиения текста на колонки -f, --file - прочитать данные не из стандартного вывода, а из файла -v, --assign - присвоить значение переменной, например foo=bar -b, --characters-as-bytes - считать все символы однобайтовыми -d, --dump-variables - вывести значения всех переменных awk по умолчанию -D, --debug - режим отладки, позволяет вводить команды интерактивно с клавиатуры -e, --source - выполнить указанный код на языке awk -o, --pretty-print - вывести результат работы программы в файл -V, --version - вывести версию утилиты. Функции: print(строка) - вывод чего либо в стандартный поток вывода printf(строка) - форматированный вывод в стандартный поток вывода system(команда) - выполняет команду в системе length(строка) - возвращает длину строки substr(строка, старт, количество) - обрезает строку и возвращает результат tolower(строка) - переводит строку в нижний регистр toupper(строка) - переводить строку в верхний регистр. В функциях можно использовать различные переменные и операторы: FNR - номер обрабатываемой строки в файле FS - разделитель полей NF - количество колонок в данной строке NR - общее количество строк в обрабатываемом тексте RS - разделитель строк, по умолчанию символ новой строки $ - ссылка на колонку по номеру. Кроме этих переменных, есть и другие, а также можно объявлять свои. Условие позволяет обрабатывать только те строки, в которых содержатся нужные нам данные, его можно использовать в качестве фильтра, как grep. Условие позволяет выполнять определенные блоки кода awk для начала и конца файла, для этого вместо регулярного выражения используйте директивы BEGIN (начало) и END (конец). Использование awk в Linux Простейшая и часто востребованная задача - выборка полей из стандартного вывода. Вы не найдете более подходящего инструмента для решения этой задачи, чем awk. По умолчанию awk разделяет поля пробелами. Если вы хотите напечатать первое поле, вам нужно просто использовать функцию print и передать ей параметр $1, если функция одна, то скобки можно опустить: echo 'one two three four' | awk '{print $1}' |