===== AWK ===== [[https://www.opennet.ru/docs/RUS/awk/|Site]]\\ ==== Назначение ==== AWK сканирует input (стандартный ввод или указываемый набор файлов) и над строками, удовлетворяющими заданному образцу, выполняет указываемые д-я\\ Формат:\\ awk [-Fc] [-f file] [files] awk [-Fc] [prog] [files] prog - программа вида: 'образец ${$ действие $}$' file - файл с AWK-программой: образец { действие } образец { действие } files - файлы, предназначенные для AWK обработки -Fc - устанавливает разделитель полей в `с` ==== Общая структура AWK программы ==== 1. Язык программирования AWK допускает использование: * полей * переменных * арифметических выражений 2. Образец: * регулярное выражение * выражение отношения * комбинация образцов * BEGIN и END 3. Действие * последовательность предложений, разделенных ";" или "\n" Предложения * вывод (печать) * присваевание * встроенная функция * управляющая структура ==== Язык AWK ==== === Поля === Каждая сканируемая строка **input** рассматривается как состоящая из полей, разделенных разделителями, по умолчанию пробел\\ На поля можно ссылаться: * $1 - первое поле * $2 - второе * $N - ... и т.д. * $0 - ссылается на всю строку целиком Строка может содержать до 100 полей === Переменные === Могут интерпретироваться как числовые или строковые, принимают значение в зависимости от контекста\\ Ссылки на поля могут интерпретироваться как переменные # первое поле принимает значение второго, увеличенное на 3 $1 = "3" + $2 # поле, номер которого зависит от переменной i $(i + 1) # # Массивы не объявляются, значения принимаются из контекста # элементу массива Х, по индексу NR, присваивается обрабатываемая строка x[NR] = $0 # элементы могут индексироваться не только числами x["apple"] ==== Образцы /patterns/ ==== === Регулярные выражения === В целом допускается все что и в **sed**\\ Из дополнительного: * **( )** - скобки для группировки * ** | ** - для альтернативы "или" * ** + ** - любая последовательность вхождений, указанного выражения, начиная с 1 * ** ? ** - 0 или 1 вхождение * ** [A-Z] ** - поддерживает группы ASCII /Olga/ - Указывает на строки, содержащие Olga. /[Oo]lga|[Mm]ike|[Mm]al/ - Указывает на строки, содержащие Olga или olga или Mike или mike или Mal или mal. /number[0-9]/ - Указывает на строки, содержащие number0 или number1 или ... number9. /\/.+\// - Указывает на строки, содержащие любое количество символов, больше или равное 1, заключенных в / /. === Выражение отношения === Принадлежность либо логическая операция\\ ~ - Содержится; !~ - Не содержится. Лог. Операция: < , < =, ==, !=, > =, > . === Комбинация образцов === Допускается логическая комбинация образцов (или, и, не (спец символами))\\ Комбинация "образец1 , образец2" означает начало и конец фрагмента /02\.95/ & & ($1 !~ /\.su/ $2 !~ /\.su/) - Указывает на строки, содержащие 02.95 и не имеющие .su одновременно в первом и во втором поле. NR == 100, NR == 200 - Указывает строки с номерами от 100 до 200. === BEGIN и END === Образец BEGIN указывает на начало **input** или на те д-я которые должны быть выполнены до какого либо анализа строк\\ Образец END указывает на конец **input** или на д-я после обработки всех строк\\ BEGIN {FS = ":"} - Устанавливает разделитель полей в ":" до начала обработки строк. Эквивалентно опции "-F:" при AWK вызове. END { print NR } - Печатает номер последней строки input, т.е. количество обработанных входных строк. ==== Действия ==== === Вывод /печать/ === PRINT [< список выражений >] [< <выражение1> ] # Если в списке выражения находятся через запятую, то значения этих выражений печатаются через символ разделитель OFS (по уолчанию пробел) # Если же выражения через пробел, то на печати происходит их конкатенация # Значение < выражение 1 > рассматривается как имя файла, его присутствие означает печатать в файл, можно использовать несколько файлов # Форматрованный вывод PRINTF формат [, список выражений ] [ > выражение1 ] # формат - символьная строка в войных кавычках, идентичен printf в C === Присваивание === Оператор присваивания имеет вид: < переменная> = < выражение> Начальное значение переменной 0 или `` '' (пробел). Допускаются другие типы присваивания в соответствии с языком ``С'': "+=","-=","*=","/=","%=". < переменная> ++, ++< переменная> - увеличение значения переменной на 1. < переменная> --, --< переменная> - уменьшение значения переменной на 1. === Встроенные функции === * length(arg) - Функция длины arg. Если arg не указан, то выдает длину текущей строки. * exp(),log(),sqrt() - Математические функции экспонента, логарифм и квадратный корень. * int() - Функция целой части числа. * substr(s,m,n) - Возвращает подстроку строки s, начиная с позиции m, всего n символов. * index(s,t) - Возвращает начальную позицию подстроки t в строке s. (Или 0, если t в s не содержится.) * sprintf(fmt,exp1,exp2,...) - Осуществляет форматированную печать (вывод) в строку, идентично PRINTF. * split(s,array,sep) - Помещает поля строки s в массив array и возвращает число заполненных элементов массива. Если указан sep, то при анализе строки он понимается как разделитель. ==== ==== :!: Переменные не объявляются, сразу используются\\ :!: Типизация слабо учитывается, конвертируется в число при первой арифметической операции, \\ в строку при первой конкатенации или пробеле\\ :!: \\ :!: \\ :!: \\ :!: \\ ==== ==== ==== ====
:!: Встроенные переменные * **ARGC (ARGV)** - Число аргументов (массив аргументов) * **ENVIRON** - Массив переменных окружения * **FILENAME** - Имя обрабатываемого файла * **FNR** - Номер записи в текущем файле * **FS** - Разделитель полей записи на вводе * **NF** - Число полей в текущей записи * **NR** - Номер записи (общее число считанных записей) * **OFMT** - Формат печати чисел * **OFS** - Разделитель полей записи на выводе * **ORS** - Разделитель записей на выводе AWK-программы * **RS** - Разделитель записи на вводе * **RSTART** - Позиция начала подстроки, найденной ф-ей **match** * **RLENGHT** - Длина подстроки, найденной **match** * **SUBSEP** - Разделитель индексов в многомерных массивах
:!: Примеры # Печать длинны самой длинной строки { if (length($0) > max) max = length($0) } END { print max } # Печать строк номера которых кратны трем { if (FNR % 3 == 0) print $0 } # Печать остатка найденной строки { # поиск начала 4-го поля... match($0,/[ \t]*[^ \t]*[ \t]*[^ \t]*[ \t]*[^ \t]*[ \t]*/) # ...печать остатка входной строки с найденной позиции print substr($0,1+RLENGTH) } # # # # #
:!: