awk
Языковый процессор для поиска и обработки текстовых данных по шаблонам
Описание
awk — мощный язык программирования и утилита для обработки текстовых файлов. Создан в 1977 году Альфредом Ахо (A), Питером Вайнбергером (W) и Брайаном Керниганом (K) в Bell Labs — отсюда название. awk автоматически разбивает каждую строку на поля, предоставляет встроенные переменные и поддерживает управляющие конструкции языка C.
Программа awk состоит из правил вида шаблон { действие }. Для каждой входной строки awk проверяет шаблон — если он совпадает, выполняется действие. Специальные правила BEGIN и END выполняются до и после обработки всех строк. Поля строки доступны как $1, $2, ..., $NF; вся строка — $0.
Существуют несколько реализаций: оригинальный awk, расширенный gawk (GNU awk, наиболее распространён в Linux) и mawk (быстрый). В большинстве систем awk является псевдонимом для одной из них. gawk добавляет массивы, сетевые возможности, функции и поддержку Unicode.
Синтаксис
- 'program' — программа awk в одинарных кавычках
- -f progfile — загрузить программу из файла
- $0 — вся строка; $1..$NF — поля; NF — число полей; NR — номер строки
- Разделитель полей: FS (по умолчанию — один/несколько пробелов)
Флаги, опции и встроенные переменные
| Флаг / Переменная | Описание | Пример |
|---|---|---|
-F SEP |
Установить разделитель полей (FS) | awk -F: '{print $1}' /etc/passwd |
-v VAR=VAL |
Установить переменную перед выполнением программы | awk -v OFS=, '{print $1,$2}' f |
-f FILE |
Читать программу из файла | awk -f script.awk data.txt |
$0 |
Вся текущая строка | awk '{print $0}' file |
$1, $2, ... |
Поля строки по порядку | awk '{print $1, $3}' file |
$NF |
Последнее поле строки | awk '{print $NF}' file |
NR |
Номер текущей записи (строки) | awk 'NR==5' file |
NF |
Количество полей в текущей строке | awk '{print NF, $0}' file |
FS |
Разделитель входных полей (Field Separator) | awk 'BEGIN{FS=","} {print $2}' |
OFS |
Разделитель выходных полей (Output Field Separator) | awk 'BEGIN{OFS="|"} {print $1,$2}' |
RS |
Разделитель записей (Record Separator, по умолчанию \n) |
awk 'BEGIN{RS="\n\n"}' file |
FILENAME |
Имя текущего обрабатываемого файла | awk '{print FILENAME, NR}' *.log |
Паттерны использования
Вычисления и агрегация
# Сумма и среднее числового поля
awk '{sum+=$1; count++} END {print "Sum:", sum, "Avg:", sum/count}' numbers.txt
# Максимальное значение
awk 'NR==1{max=$1} $1>max{max=$1} END{print max}' file
Фильтрация строк
# Строки с условием по полю awk '$3 > 100' data.txt awk '$1 == "ERROR"' log.txt # С регулярным выражением awk '/pattern/' file awk '!/comment/' config.txt # без комментариев
Форматированный вывод
awk '{printf "%-20s %5d\n", $1, $2}' data.txt
# Заголовок и данные
awk 'BEGIN{printf "%-10s %s\n","Name","Value"}
{printf "%-10s %s\n",$1,$2}' data.txt
Подсчёт с группировкой
# Частота слов
awk '{for(i=1;i<=NF;i++) count[$i]++}
END{for(w in count) print count[w], w}' text.txt | sort -rn
Обработка CSV / изменение полей
# Поменять порядок колонок
awk -F',' '{print $2","$1","$3}' data.csv
# Добавить вычисляемое поле
awk -F',' '{print $0","$2*$3}' prices.csv
Многострочная обработка
# BEGIN и END
awk 'BEGIN{print "Start"}
{total += $1}
END{print "Total:", total}' nums.txt
# Нумерация строк
awk '{print NR": "$0}' file.txt
Советы и предупреждения
-v OFS=',' для изменения разделителя вывода:
awk -F: -v OFS=',' '{print $1,$3,$6}' /etc/passwd — конвертирует из формата passwd в CSV.
awk '{count[$1]++} END{for(k in count) print k, count[k]}' log
sub() и gsub():
awk '{gsub(/old/, "new"); print}' file — заменить все вхождения в каждой строке.
., +, *), экранируйте их: awk -F'\.' для точки.
awk строки и числа автоматически преобразуются. "10" > "9" в строковом сравнении даст false (лексикографически «1» < «9»), поэтому для чисел используйте +0: $1+0 > 9.