Команда awk в Linux: полное руководство по обработке и анализу текстовых данных

24.02.2026
13:23

Когда нужно быстро извлечь третий столбец из лог-файла на 100,000 строк, подсчитать сумму чисел в CSV или найти дубликаты в конфигурационных файлах, опытные системные администраторы тянутся к одному инструменту — awk. Эта утилита командной строки существует с 1977 года, но до сих пор остается незаменимой для обработки структурированного текста.

В отличие от Python скриптов которые нужно писать и отлаживать, awk позволяет решать большинство задач обработки текста одной строкой кода. В отличие от grep который просто ищет паттерны, awk анализирует структуру данных по столбцам и строкам, выполняет математические вычисления и форматирует вывод.

В этом руководстве покажем как использовать awk для повседневных задач системного администратора: анализ логов веб-сервера, обработка CSV файлов, мониторинг системных ресурсов и автоматизация рутинных операций. Все примеры протестированы на реальных серверах THE.Hosting и готовы к использованию.

Что такое awk и зачем он нужен

AWK — это язык программирования и утилита командной строки для обработки текстовых данных в Unix и Linux системах. Название происходит от фамилий создателей: Aho, Weinberger и Kernighan, которые разработали язык в Bell Labs в 1977 году.

Основная концепция awk: программа читает входной текст построчно, разбивает каждую строку на поля (столбцы) по разделителю и выполняет указанные действия над этими полями. Это делает awk идеальным для работы со структурированными данными — логами, CSV файлами, выводом системных команд, конфигурационными файлами.

Когда использовать awk:

  • Извлечение конкретных столбцов из таблиц данных
  • Фильтрация строк по условиям (больше/меньше, содержит текст)
  • Вычисления по столбцам (сумма, среднее, подсчет)
  • Форматирование вывода других команд
  • Обработка CSV, TSV, лог-файлов
  • Быстрый анализ больших текстовых файлов без загрузки в память

Сравнение с альтернативами:

Инструмент Когда использовать Сложность
awk Работа со столбцами, вычисления, форматирование Средняя
grep Простой поиск строк по паттерну Низкая
sed Замена текста, редактирование потока Средняя
cut Извлечение фиксированных столбцов Низкая
Python Сложная логика, большие проекты Высокая

Реальный пример: У вас есть лог веб-сервера с 50,000 строк. Нужно найти все запросы к API эндпоинту /api/users и посчитать сколько раз каждый IP адрес обращался. С awk это одна строка:

awk '/\/api\/users/ {count[$1]++} END {for (ip in count) print ip, count[ip]}' access.log

Эквивалентный Python скрипт занял бы 15-20 строк кода.

Синтаксис команды awk

Базовая структура:

awk 'pattern {action}' файл
  • pattern — условие отбора строк (опционально)
  • action — действие над строками которые соответствуют условию
  • файл — входной файл (можно несколько или stdin через pipe)

Основные варианты использования:

Печать всех строк (как cat):

awk '{print}' file.txt

Печать первого столбца:

awk '{print $1}' file.txt

Строки содержащие "error":

awk '/error/ {print}' file.txt

С условием на значение столбца:

awk '$3 > 100 {print $1, $3}' file.txt

Несколько действий через точку с запятой:

awk '{sum += $2; count++} END {print sum/count}' file.txt

Важные опции командной строки:

Опция Описание Пример
-F Указать разделитель полей awk -F':' '{print $1}' /etc/passwd
-v Передать переменную в программу awk -v limit=100 '$3 > limit'
-f Читать программу из файла awk -f script.awk data.txt

Разделители полей:

По умолчанию awk разбивает строки по пробелам и табуляциям. Для других разделителей:

CSV файл (запятая):

awk -F',' '{print $1, $3}' data.csv

Файл /etc/passwd (двоеточие):

awk -F':' '{print $1, $6}' /etc/passwd

Несколько символов разделителей:

awk -F'[,:]' '{print $1}' mixed.txt

Регулярное выражение как разделитель:

awk -F'[[:space:]]+' '{print $1}' file.txt

Базовые концепции awk

Поля и записи

Запись (Record) — строка входного текста. Awk обрабатывает файл построчно.

Поле (Field) — столбец в записи, разделенный специальным символом.

Обозначение полей:

  • $0 — вся строка целиком
  • $1 — первое поле (первый столбец)
  • $2 — второе поле
  • $NF — последнее поле (NF = number of fields)
  • $(NF-1) — предпоследнее поле

Пример данных (employees.txt):

John Manager Sales 5000
Alice Developer IT 6000
Bob Analyst Finance 4500

Работа с полями:

Печать имени и зарплаты

awk '{print $1, $4}' employees.txt

Переставить столбцы местами

awk '{print $4, $2, $1}' employees.txt

Конкатенация строк

awk '{print $1 " работает в " $3}' employees.txt

Арифметика

awk '{print $1, $4 * 1.15}' employees.txt

Паттерны (условия)

Паттерны определяют какие строки обрабатывать.

Типы паттернов:

1. Регулярные выражения (между слэшами):

Печатает строки содержащие "IT":

awk '/IT/ {print}' employees.txt

2. Сравнение полей:

Печатает сотрудников с зарплатой > 5000:

awk '$4 > 5000 {print $1, $4}' employees.txt

3. Логические операторы:

Оператор И (AND) — отдел Sales И зарплата > 4000:

awk '$3 == "Sales" && $4 > 4000 {print}' employees.txt

Оператор ИЛИ (OR) — зарплата < 5000 ИЛИ должность Manager:

awk '$4 < 5000 || $2 == "Manager" {print}' employees.txt

4. Диапазоны строк:

Печатает строки от паттерна START до END включительно:

awk '/START/,/END/ {print}' file.txt

5. Отрицание:

Все кроме отдела IT:

awk '$3 != "IT" {print}' employees.txt

Строки НЕ содержащие Manager:

awk '!/Manager/ {print}' employees.txt

Операторы сравнения:

Оператор Значение Пример
== Равно $1 == "John"
!= Не равно $2 != "Sales"
< Меньше $3 < 100
> Больше $3 > 1000
<= Меньше или равно $3 <= 50
>= Больше или равно $3 >= 100
~ Соответствует regex $1 ~ /^A/
!~ Не соответствует regex $1 !~ /test/

Специальные паттерны BEGIN и END

BEGIN — выполняется один раз перед обработкой данных
END — выполняется один раз после обработки всех данных

Заголовок и итог

awk 'BEGIN {print "Имя\tЗарплата"}
{print $1, $4}
END {print "---\nВсего сотрудников:", NR}' employees.txt

Практический пример — вычисление среднего:

awk 'BEGIN {sum=0; count=0}
{sum += $4; count++}
END {print "Средняя зарплата:", sum/count}' employees.txt

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

Awk предоставляет набор предопределенных переменных для работы с данными.

Переменная Описание Пример использования
NR Number of Records — номер текущей строки {print NR, $0}
NF Number of Fields — количество полей в строке {print $NF} (последнее поле)
FS Field Separator — разделитель входных полей BEGIN {FS=":"} {print $1}
OFS Output Field Separator — разделитель выходных полей BEGIN {OFS=","} {print $1, $2}
RS Record Separator — разделитель входных записей BEGIN {RS=";"} {print}
ORS Output Record Separator — разделитель выходных записей BEGIN {ORS="---\n"} {print}
FILENAME Имя текущего обрабатываемого файла {print FILENAME, $0}
FNR Номер строки в текущем файле {print FILENAME, FNR, $0}

Примеры использования:

Нумерация строк

awk '{print NR, $0}' file.txt

Вывод количества полей в каждой строке

awk '{print "Строка", NR, "содержит", NF, "полей"}' data.txt

Изменение разделителя вывода

awk 'BEGIN {OFS=" | "} {print $1, $2, $3}' file.txt

Обработка нескольких файлов

awk '{print FILENAME, FNR, $1}' file1.txt file2.txt

Операции и вычисления в awk

Арифметические операции

Базовые операции: + - * / % (остаток от деления)

awk '{print $1, $2 * 1.2}' file.txt

Увеличение значения

awk '{$4 = $4 * 1.15; print}' employees.txt

Накопление суммы

awk '{sum += $3} END {print "Итого:", sum}' sales.txt

Счетчик

awk '/error/ {count++} END {print "Ошибок:", count}' log.txt

Строковые операции

Конкатенация строк (просто пробел)

awk '{print $1 $2}' file.txt          # JohnDoe
awk '{print $1 " " $2}' file.txt      # John Doe
awk '{print $1 "-" $2}' file.txt      # John-Doe

Функция length() — длина строки

awk '{print $1, length($1)}' file.txt
awk 'length($0) > 80 {print}' file.txt  # Строки длиннее 80 символов

Функция substr() — подстрока

awk '{print substr($1, 1, 3)}' file.txt  # Первые 3 символа

Функция tolower() и toupper()

awk '{print tolower($1)}' file.txt
awk '{print toupper($1)}' file.txt

Функция gsub() — замена всех вхождений

awk '{gsub(/old/, "new"); print}' file.txt

Функция sub() — замена первого вхождения

awk '{sub(/old/, "new"); print}' file.txt

Функция match() — поиск паттерна

awk 'match($0, /[0-9]+/) {print substr($0, RSTART, RLENGTH)}' file.txt

Условные конструкции

If-else:

Базовый if

awk '{if ($3 > 5000) print $1, "высокая зарплата"}' employees.txt

If-else

awk '{if ($4 > 5000)
print $1, "высокая"
else
print $1, "низкая"}' employees.txt

Многострочная программа

awk '{
if ($4 >= 6000)
category = "senior"
else if ($4 >= 5000)
category = "middle"
else
category = "junior"
print $1, category
}' employees.txt

Тернарный оператор:

awk '{print $1, ($4 > 5000 ? "high" : "low")}' employees.txt

Циклы

For цикл:

Вывод всех полей построчно

awk '{for (i=1; i<=NF; i++) print i, $i}' file.txt

Сумма всех чисел в строке

awk '{sum=0; for(i=1; i<=NF; i++) sum+=$i; print sum}' numbers.txt

While цикл:

awk '{i=1; while(i<=NF) {print i":"$i; i++}}' file.txt

Массивы в awk

Массивы в awk ассоциативные (как хеш-таблицы) — ключом может быть любая строка.

Базовое использование массивов

Подсчет уникальных значений

awk '{count[$1]++} END {for (name in count) print name, count[name]}' file.txt

Суммирование по категориям

awk '{sales[$3] += $4}
END {for (dept in sales) print dept, sales[dept]}' data.txt

Практические примеры с массивами

Подсчет IP адресов в логе:

awk '{ip_count[$1]++} 
     END {for (ip in ip_count) print ip, ip_count[ip]}' access.log | sort -rn -k2

Группировка по статусам HTTP:

awk '{status[$9]++} 
     END {for (code in status) print code, status[code]}' access.log

Нахождение дубликатов:

awk '{if (seen[$0]++) print "Дубликат:", $0}' file.txt

Удаление дубликатов (вывод уникальных строк):

awk '!seen[$0]++' file.txt

Практические примеры для реальных задач

Анализ логов веб-сервера

Формат access.log:

192.168.1.100 - - [24/Feb/2026:10:15:30 +0000] "GET /index.html HTTP/1.1" 200 1234

Топ-10 IP адресов по количеству запросов:

awk '{ip[$1]++} END {for (i in ip) print ip[i], i}' access.log | sort -rn | head -10

Подсчет запросов по HTTP методам:

awk '{print $6}' access.log | sort | uniq -c

Фильтрация ошибок 404:

awk '$9 == 404 {print $7}' access.log | sort | uniq -c | sort -rn

Трафик по часам:

awk '{print substr($4, 14, 2)}' access.log | sort | uniq -c

Обработка CSV файлов

Пример CSV (sales.csv):

Date,Product,Quantity,Price
2026-02-01,Widget,10,25.50
2026-02-01,Gadget,5,120.00
2026-02-02,Widget,8,25.50

Вычисление общей выручки:

awk -F',' 'NR>1 {sum += $3 * $4} END {print "Total:", sum}' sales.csv

Сумма по продуктам:

awk -F',' 'NR>1 {total[$2] += $3 * $4} 
           END {for (p in total) print p, total[p]}' sales.csv

Фильтрация по дате:

awk -F',' '$1 ~ /2026-02-01/ {print $2, $3}' sales.csv

Форматированный вывод с заголовками:

awk -F',' 'BEGIN {print "Product | Total"} 
           NR>1 {total[$2] += $3 * $4} 
           END {for (p in total) printf "%-10s | $%.2f\n", p, total[p]}' sales.csv

Системное администрирование

Мониторинг использования диска:

df -h | awk 'NR>1 {if ($5+0 > 80) print $6, "занято", $5}'

Топ процессов по памяти:

ps aux | awk 'NR>1 {print $11, $4"%"}' | sort -k2 -rn | head -10

Анализ активных соединений:

netstat -an | awk '/ESTABLISHED/ {count[$5]++} 
                   END {for (ip in count) print ip, count[ip]}' | sort -rn -k2

Проверка открытых портов:

netstat -tuln | awk 'NR>2 {print $4}' | awk -F':' '{print $NF}' | sort -n | uniq

Обработка конфигурационных файлов

Извлечение активных пользователей из /etc/passwd:

awk -F':' '$7 !~ /nologin|false/ {print $1, $6}' /etc/passwd

Пользователи с UID > 1000:

awk -F':' '$3 >= 1000 {print $1, $3}' /etc/passwd

Группы пользователя:

awk -F':' '/^username:/ {print $4}' /etc/passwd | 
  xargs -I {} awk -F':' '$3 == {} {print $1}' /etc/group

Продвинутые техники

Многофайловая обработка

Сравнение двух файлов

awk 'NR==FNR {a[$1]; next} $1 in a' file1.txt file2.txt

Разница файлов

awk 'NR==FNR {a[$1]; next} !($1 in a)' file1.txt file2.txt

Форматирование вывода с printf

Выравнивание столбцов

awk '{printf "%-10s %8.2f\n", $1, $2}' file.txt

Таблица с заголовками

awk 'BEGIN {printf "%-10s %10s %10s\n", "Name", "Salary", "Dept"}
{printf "%-10s %10d %10s\n", $1, $4, $3}' employees.txt

Вызов внешних команд

Выполнение shell команды

awk '{system("echo Processing: " $1)}' file.txt

Чтение вывода команды

awk 'BEGIN {
cmd = "date"
cmd | getline result
close(cmd)
print result
}'

Создание отчетов

Подробный отчет по логам:

awk 'BEGIN {
  print "=== Web Server Report ==="
  print "Generated:", strftime("%Y-%m-%d %H:%M:%S")
}
{
  requests++
  bytes += $10
  status[$9]++
  if ($9 >= 400) errors++
}
END {
  print "\nTotal Requests:", requests
  print "Total Traffic:", bytes/1024/1024, "MB"
  print "Error Rate:", (errors/requests)*100 "%"
  print "\nStatus Codes:"
  for (code in status) 
    printf "  %s: %d (%.1f%%)\n", code, status[code], (status[code]/requests)*100
}' access.log

Сравнение awk с альтернативами

awk vs sed

awk лучше для:

  • Работы со столбцами данных
  • Математических вычислений
  • Сложной логики (условия, циклы)
  • Создания отчетов

sed лучше для:

  • Простой замены текста
  • Редактирования потока
  • Удаления строк
  • Вставки текста

Пример задачи: Извлечь email адреса из текста

awk

awk 'match($0, /[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z]{2,}/) {
print substr($0, RSTART, RLENGTH)
}' file.txt

sed (сложнее и менее читабельно)

sed -n 's/.*\([a-zA-Z0-9._-]\+@[a-zA-Z0-9._-]\+\.[a-zA-Z]\{2,\}\).*/\1/p' file.txt

awk vs Python

awk преимущества:

  • Быстрее для простых задач (нет накладных расходов на интерпретатор)
  • Короче код для типичных операций
  • Встроен в любой Linux
  • Удобнее в pipe цепочках

Python преимущества:

  • Больше возможностей стандартной библиотеки
  • Лучше для сложной логики
  • Проще отладка
  • Больше документации

Сравнение кода — подсчет средней зарплаты:

awk (1 строка)

awk '{sum+=$4; count++} END {print sum/count}' employees.txt

Python (минимум 7 строк)

with open('employees.txt') as f:
total = 0
count = 0
for line in f:
salary = int(line.split()[3])
total += salary
count += 1
print(total / count)

Оптимизация и лучшие практики

Производительность

1. Избегайте ненужных операций:

Плохо - проверка на каждой строке

awk '{if (NR > 1) print}' file.txt

Хорошо - используйте диапазон

awk 'NR > 1' file.txt

2. Используйте встроенные переменные:

Медленно

awk '{print $1, $2, $3, $4}' file.txt

Быстрее

awk '{$5=""; print}' file.txt

3. Фильтруйте рано:

Плохо - обрабатывает все строки

awk '{sum += $3} $2 == "Sales" {print}' file.txt

Хорошо - фильтрует сразу

awk '$2 == "Sales" {sum += $3; print}' file.txt

Читабельность кода

Используйте переменные:

Плохо

awk '$3 > 5000 && $4 == "IT" {print $1}' file.txt

Хорошо

awk '{
salary = $3
dept = $4
name = $1
if (salary > 5000 && dept == "IT")
print name
}' file.txt

Выносите сложные программы в файлы:

script.awk

BEGIN {
FS = ","
OFS = " | "
total = 0
}
NR > 1 {
total += $3 * $4
printf "%s | %s | %.2f\n", $1, $2, $3 * $4
}
END {
print "---"
printf "Total: $%.2f\n", total
}

Использование:

awk -f script.awk data.csv

Распространенные ошибки и решения

Проблема: Неправильный разделитель полей

Ошибка - CSV обрабатывается как пробелы

awk '{print $2}' data.csv

Решение - указать разделитель

awk -F',' '{print $2}' data.csv

Проблема: Пропуск заголовка

Ошибка - заголовок участвует в вычислениях

awk '{sum += $2} END {print sum}' file.csv

Решение 1 - начать со второй строки

awk 'NR > 1 {sum += $2} END {print sum}' file.csv

Решение 2 - пропустить нечисловые

awk '{if ($2 ~ /^[0-9]+$/) sum += $2} END {print sum}' file.csv

Проблема: Деление на ноль

Ошибка - возможно деление на ноль

awk '{print $1 / $2}' file.txt

Решение - проверка

awk '{if ($2 != 0) print $1 / $2; else print "N/A"}' file.txt

Проблема: Пробелы в полях CSV

Ошибка - поле "New York" разбивается на два

awk -F',' '{print $3}' cities.csv

Решение - обрезка пробелов

awk -F',' '{gsub(/^ +| +$/, "", $3); print $3}' cities.csv

Частые вопросы (FAQ)

Как вывести последнюю колонку?

awk '{print $NF}' file.txt

Как вывести все кроме первой колонки?

awk '{$1=""; print}' file.txt

Или чище:

awk '{for(i=2;i<=NF;i++) printf "%s ", $i; print ""}' file.txt

Как подсчитать количество строк?

awk 'END {print NR}' file.txt

Или просто

wc -l file.txt

Как обработать файлы с путями содержащими пробелы?

Используйте переменную FILENAME

awk '{print FILENAME, $0}' "file with spaces.txt"

Как вывести строки между двумя паттернами?

awk '/START/,/END/' file.txt

Как удалить дубликаты сохранив порядок?

awk '!seen[$0]++' file.txt

Можно ли изменить исходный файл?

Нет, awk только читает. Для записи:

awk '{print $1, $2}' input.txt > output.txt

Как обработать JSON в awk?

Awk плохо подходит для JSON. Используйте jq:

jq '.items[] | .name' file.json

Установка и версии awk

Проверка установленной версии:

awk --version

или

which awk

Основные реализации:

  • gawk — GNU Awk, самая распространенная в Linux
  • mawk — быстрая реализация, меньше функций
  • nawk — "new awk", стандарт POSIX
  • оригинальный awk — устаревший, в современных системах обычно это симлинк на gawk

Установка на разных системах:

Ubuntu/Debian

sudo apt install gawk

CentOS/RHEL

sudo yum install gawk

macOS

brew install gawk

На серверах THE.Hosting gawk предустановлен на всех тарифах и готов к использованию.

Заключение

Команда awk — незаменимый инструмент в арсенале системного администратора и DevOps инженера. Она позволяет за секунды решать задачи которые потребовали бы десятков строк кода на других языках.

Основные преимущества awk: работа со структурированными данными по столбцам, встроенная поддержка регулярных выражений, математические вычисления, минималистичный синтаксис для простых задач и возможность создания сложных программ для продвинутых сценариев.

Изучив базовые концепции из этого руководства вы сможете: анализировать лог-файлы веб-серверов и приложений, обрабатывать CSV и другие табличные данные, автоматизировать рутинные операции с текстом, мониторить системные ресурсы и строить отчеты.

На серверах THE.Hosting вы можете использовать awk для анализа логов веб-сервера, мониторинга нагрузки и автоматизации задач администрирования. Все современные дистрибутивы Linux на наших VPS включают GNU Awk готовый к работе.

Заказать VPS для работы с Linux

Дополнительные ресурсы:

Содержание:
Закажите новый VPS со скидкой 15%
Любая локация на выбор. Стабильный сервер для ваших проектов по выгодной цене.
Выбрать VPS

Другие статьи