===== 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)
}
#
#
#
#
#
:!: