sed и awk
| sed | Ли Макмэхон, Bell Labs (1973–1974) |
|---|---|
| awk | Альфред Ахо, Питер Вайнбергер, Брайан Керниган (1977) |
| Название awk | по первым буквам фамилий авторов |
| Реализации | GNU sed и gawk, BSD sed, mawk, BusyBox |
| Стандарт | POSIX |
| Книга | The AWK Programming Language (1988, 2-е изд. 2023) |
sed (от stream editor — потоковый редактор) и awk — классические утилиты Unix для обработки текста. sed читает поток строк и применяет к нему команды редактирования: замену по регулярным выражениям, удаление и вставку строк. awk — небольшой язык программирования для данных, разбитых на поля: он перебирает строки, делит каждую на столбцы и выполняет действия для строк, подходящих под шаблон.
Обе утилиты есть в любой Unix-подобной системе и незаменимы в конвейерах и скриптах на Bash: поправить конфигурацию, вытащить столбец из лога, посчитать сумму.
История
sed написал Ли Макмэхон в Bell Labs в 1973–1974 годах на основе команд строкового редактора ed: идея была применять те же команды к потоку, не открывая файл интерактивно. awk создали в 1977 году Альфред Ахо, Питер Вайнбергер и Брайан Керниган — название составлено из первых букв их фамилий. В 1988 году авторы выпустили книгу «The AWK Programming Language», а в 2023 году — второе издание.[5] Поведение обеих утилит закреплено в POSIX.[3][4]
sed
sed 's/http:/https:/' urls.txt # заменить первое вхождение в каждой строке
sed 's/http:/https:/g' urls.txt # все вхождения
sed -n '10,20p' big.log # напечатать строки 10–20
sed '/^#/d; /^$/d' config.conf # удалить комментарии и пустые строки
sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3.\2.\1/' dates.txt # 2026-11-09 → 09.11.2026
sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config # правка файла на месте
Основная команда — s/шаблон/замена/флаги. Флаг g заменяет все вхождения, I — без учёта регистра; ключ -E включает расширенные регулярные выражения, а в замене \1, \2 подставляют группы, & — всё найденное. Перед командой можно указать адрес: номер строки, диапазон или шаблон (/ERROR/s/.../.../).[1]
Внимание: sed -i различается в GNU (Linux) и BSD (macOS): на macOS нужен аргумент суффикса резервной копии, хотя бы пустой — sed -i '' 's/a/b/' file. Переносимый вариант — sed -i.bak ... с последующим удалением .bak-файла.
awk
Программа awk — набор правил шаблон { действие }. Каждая строка делится на поля $1, $2, …; $0 — вся строка, NF — число полей, NR — номер строки. Разделитель задаётся ключом -F.
awk '{print $1}' access.log # первый столбец (IP-адрес)
awk -F: '{print $1, $7}' /etc/passwd # пользователь и его оболочка
awk '$9 >= 500' access.log # строки, где код ответа ≥ 500
awk '{sum += $10} END {print sum/1024/1024 " МБ"}' access.log # сумма по столбцу
awk -F, 'NR > 1 {total[$2] += $3} END {for (c in total) print c, total[c]}' sales.csv # группировка
awk 'length > 120 {print FILENAME ":" FNR}' *.py # строки длиннее 120 символов
Блок BEGIN выполняется до чтения данных, END — после. Ассоциативные массивы (total[$2]) делают awk удобным для подсчётов и группировки — аналога GROUP BY в SQL. Полное описание языка — в руководстве GNU Awk.[2]
Примеры конвейеров
# топ-10 IP-адресов по числу запросов
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head
# среднее время ответа по эндпоинтам из лога вида: GET /api/users 200 123ms
awk '{gsub("ms", "", $4); t[$2] += $4; n[$2]++} END {for (u in t) printf "%-30s %6.1f\n", u, t[u]/n[u]}' app.log | sort -k2 -rn
# заменить версию во всех файлах проекта
grep -rl 'version = "1.2.0"' . | xargs sed -i.bak 's/version = "1.2.0"/version = "1.3.0"/'
Здесь sed и awk работают вместе с grep, sort, uniq и xargs — каждый делает одно дело, а конвейер решает задачу целиком.
Когда что использовать
| Задача | Инструмент |
|---|---|
| Найти строки | grep |
| Заменить текст, удалить строки | sed |
| Работать со столбцами, считать, группировать | awk |
| JSON | jq |
| CSV с кавычками и запятыми внутри полей | специализированные инструменты (Miller, csvkit) или Python |
| Логика сложнее нескольких строк | Python |
Типичные ошибки
- Одинарные кавычки вокруг программы обязательны: иначе оболочка раскроет
$1и*до того, как их увидит awk или sed. - Символ
/в шаблоне нужно экранировать или сменить разделитель:sed 's|/usr/local|/opt|g'. sed -iбез резервной копии на важных файлах — сначала проверьте результат без-i.- awk по умолчанию делит по пробелам и табуляции; для CSV с запятыми внутри кавычек он не подходит.
См. также
- grep и регулярные выражения
- Регулярные выражения
- Конвейеры и перенаправление (pipes)
- find и xargs
- Shell и Bash