Перейти к содержанию

Регулярные выражения

Шпаргалка по regex для LPIC-1: grep, sed, awk.

BRE vs ERE

Тип Команды Особенности
BRE (базовые) grep, sed, vi +, ?, |, (), {} нужно экранировать: \+ \? \|
ERE (расширенные) grep -E, egrep, awk +, ?, |, (), {} работают без \

Метасимволы

Общие (BRE и ERE)

Символ Значение Пример Совпадает
. Любой символ кроме \n c.t cat, cut, c3t
^ Начало строки ^root строки, начинающиеся с root
$ Конец строки bash$ строки, оканчивающиеся на bash
* 0 или более предыдущего lo*g lg, log, looog
[abc] Любой из символов [aeiou] один гласный
[^abc] Ни один из символов [^0-9] не цифра
[a-z] Диапазон [a-zA-Z] любая буква
\ Экранирование \. буквальная точка

Только ERE

Символ Значение Пример Совпадает
+ 1 или более lo+g log, looog (не lg)
? 0 или 1 colou?r color, colour
\| Альтернатива cat\|dog cat или dog
() Группировка (ha)+ ha, haha
{n} Ровно n раз [0-9]{3} трёхзначное число
{n,} n или более [0-9]{2,} 2+ цифры
{n,m} От n до m [0-9]{2,4} 2–4 цифры

Классы символов POSIX

Используются внутри []: grep '[[:digit:]]'

Класс Эквивалент Описание
[:alpha:] [a-zA-Z] Буквы
[:digit:] [0-9] Цифры
[:alnum:] [a-zA-Z0-9] Буквы и цифры
[:space:] [ \t\n\r] Пробельные символы
[:upper:] [A-Z] Заглавные
[:lower:] [a-z] Строчные
[:blank:] [ \t] Пробел и табуляция
[:punct:] Знаки пунктуации

grep

grep [опции] 'шаблон' файл
Опция Описание
-i Без учёта регистра
-v Инвертировать (строки без совпадения)
-n Показать номера строк
-c Количество совпадающих строк
-l Только имена файлов с совпадениями
-r Рекурсивный поиск
-E Расширенные regex (ERE)
-o Только совпадающую часть
-w Целое слово
-A n n строк после совпадения
-B n n строк до совпадения
-C n n строк вокруг совпадения
grep -n '^root' /etc/passwd              # строки, начинающиеся с root
grep -v '^#' /etc/ssh/sshd_config        # без комментариев
grep -E '(eth|ens)[0-9]+' /proc/net/dev  # сетевые интерфейсы
grep -c 'Failed' /var/log/auth.log       # количество ошибок входа
grep -r 'TODO' /home/user/project/       # рекурсивный поиск
grep -w 'root' /etc/passwd               # только слово "root" целиком

sed

sed [опции] 'команда' файл

Команды

Команда Описание
s/old/new/ Заменить первое вхождение в строке
s/old/new/g Заменить все вхождения
s/old/new/2 Заменить второе вхождение
s/old/new/gi Все + без учёта регистра
d Удалить строку
p Напечатать строку
q Выйти после строки
a\текст Добавить строку после
i\текст Вставить строку до
y/abc/ABC/ Транслитерация символов

Опции

Опция Описание
-n Подавить вывод (только явный p)
-i Изменить файл на месте
-i.bak Изменить файл, создав резервную копию
-e Несколько команд

Адресация строк

Адрес Описание
5 Строка номер 5
5,10 Строки 5–10
$ Последняя строка
/шаблон/ Строки, совпадающие с шаблоном
/start/,/end/ Диапазон между шаблонами
1~2 Нечётные строки (1, 3, 5...)
sed 's/foo/bar/g' file.txt              # замена во всём файле
sed -n '5,10p' file.txt                 # напечатать строки 5–10
sed '/^#/d' config.conf                 # удалить комментарии
sed -i.bak 's/old/new/g' file.txt       # изменить файл с резервной копией
sed -n '/START/,/END/p' file.txt        # диапазон между шаблонами
sed -e 's/foo/bar/' -e 's/baz/qux/' f  # несколько замен
sed '2a\новая строка' file.txt          # вставить строку после 2-й

awk

awk 'шаблон { действие }' файл
awk -F: 'шаблон { действие }' файл    # разделитель полей ':'

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

Переменная Описание
$0 Вся текущая строка
$1, $2... Поля (разделитель — FS)
NR Номер текущей строки
NF Количество полей в строке
FS Разделитель полей (по умолч. пробел)
OFS Разделитель выходных полей
RS Разделитель записей (по умолч. \n)
FILENAME Имя текущего файла

Блоки BEGIN и END

awk 'BEGIN { FS=":"; OFS="\t" }
     { print $1, $3 }
     END { print "Всего строк:", NR }' /etc/passwd
awk '{print $1}' /etc/passwd                  # первое поле
awk -F: '{print $1,$3}' /etc/passwd           # имя и UID
awk -F: '$3 >= 1000 {print $1}' /etc/passwd   # обычные пользователи
awk 'NR==1,NR==5' file.txt                    # строки 1–5
awk '$2 > 100 {sum += $2} END {print sum}'    # сумма второго поля
awk '{print NF, $0}' file.txt                 # число полей в строке
awk '!seen[$0]++' file.txt                    # убрать дубли строк