linux-labs

Вики / Базовые команды

sed и awk (обработка текста)

Команда GNU sed/awk БазовоеТекст и потоки

Потоковое редактирование (sed) и обработка по столбцам (awk).

  • sed — потоковый редактор: замены, удаление/вставка строк.
  • awk — обработка по полям (столбцам): фильтры, вычисления, отчёты.

Оба читают построчно из файла или конвейера. Для сложного — используй regex.

sed 's/foo/bar/' file             # заменить ПЕРВОЕ foo в каждой строке
sed 's/foo/bar/g' file            # заменить ВСЕ (g = global)
sed -i 's/foo/bar/g' file         # править файл на месте (-i)
sed -i.bak 's/foo/bar/g' file     # с резервной копией file.bak
sed -E 's/(a|b)+/X/g' file        # extended regex (-E)
sed -n '10,20p' file              # вывести строки 10–20 (-n + p)
sed '/^#/d;/^$/d' file            # удалить комментарии И пустые строки
sed '2d' file                     # удалить 2-ю строку ; '$d' — последнюю
sed '/pattern/d' file             # удалить строки по шаблону
sed 's#/old/path#/new/path#g' f   # другой разделитель (когда в шаблоне /)
sed -i '/^KEY=/c\KEY=value' conf  # заменить целую строку по шаблону
sed -i '/anchor/a\new line' file  # добавить строку ПОСЛЕ совпадения (a=after, i=before)

sed -i меняет файл необратимо — для важного -i.bak.

awk '{print $1}' file             # первый столбец
awk '{print $1, $3}' file         # столбцы 1 и 3
awk -F: '{print $1}' /etc/passwd  # разделитель «:» — имена пользователей
awk '$3 > 1000 {print $1}' /etc/passwd -F:   # фильтр по полю
awk 'NR>1' file                   # пропустить заголовок
awk '/error/{c++} END{print c}' log          # счётчик совпадений
awk '{sum+=$1} END{print sum}' f             # сумма столбца
awk '{a[$1]+=$2} END{for(k in a)print k,a[k]}' f   # группировка/агрегация
awk 'NR==FNR{m[$1]=$2;next} {print $0, m[$1]}' map data   # «join» двух файлов
awk -F, 'BEGIN{OFS="\t"} {print $2,$1}' data.csv         # CSV→TSV, поменять колонки

Поля: $1..$N — столбцы, $0 — вся строка, NF — число полей, NR/FNR — номер строки (общий / в текущем файле); блоки BEGIN{}/END{}.

sed -i ничего не меняет

Проверь шаблон (регистр, спецсимволы / . * [ ]). Экранируй или смени разделитель (s#a#b#). Перед -i прогони без него — посмотри вывод.

awk печатает пустоту

Неверный разделитель полей: добавь -F: (или нужный). Проверь, что столбец есть (NF). Учти: пробелы по умолчанию схлопываются, табы/CSV — задавай -F.

Нужна замена в куче файлов

grep -rl old . найдёт файлы, затем grep -rlZ old . | xargs -0 sed -i 's/old/new/g' (сперва проверь список! см. xargs).

sed \n в замене / многострочное

Однострочный sed работает построчно; для многострочных операций — -z (NUL-режим) или переходи на grep/awk/perl.

sed -i 's/old/new/g' file         # замена на месте (всё)
sed -n '5,10p' file               # строки 5–10
sed -i '/^#/d;/^$/d' file         # убрать комментарии и пустые
awk '{print $1}' file ; awk -F: '{print $1}' /etc/passwd
awk '{s+=$1} END{print s}' file   # сумма столбца
awk 'NR==FNR{m[$1]=$2;next}{print $0,m[$1]}' map data   # join

См. также