Введение
Регулярное выражение описывает текст по его структуре, а не по одной точной строке. Один и тот же язык шаблонов используется во многих инструментах Linux, но каждый инструмент применяет его по-своему: grep выбирает или извлекает совпадения, sed преобразует поток, а awk объединяет шаблоны с действиями, учитывающими поля.
Сначала вы познакомитесь с якорями и классами символов, затем перейдёте к расширенным повторениям и извлечению совпадений, научитесь предварительно просматривать преобразования перед сохранением и завершите работу выбором полей и агрегацией. Шаблоны заключаются в кавычки, чтобы оболочка передавала специальные символы текстовому инструменту, а не интерпретировала их самостоятельно.
Сопоставление строк с базовой структурой регулярных выражений
На этом этапе вы будете использовать обычный текст, якоря и классы символов для описания позиций во всей строке.
Просмотрите учебный файл:
cd /home/labex/project/regex-lab
nl -ba contacts.txt
Обычный текст сопоставляется в любом месте строки:
grep 'active' contacts.txt
Символ ^ привязывает шаблон к началу строки, а $ — к её концу. Найдите запись Alice и записи, заканчивающиеся двузначным числом:
grep '^Alice|' contacts.txt
grep '[0-9][0-9]$' contacts.txt
В квадратных скобках класс символов сопоставляется с одним символом. [ABC] означает A, B или C:
grep '^[ABC]' contacts.txt | tee abc-contacts.txt
Эта команда выводит записи Alice, Bob и Carol. Также сохраните числовые совпадения, привязанные к концу строки:
grep '[0-9][0-9]$' contacts.txt > two-digit-values.txt
Использование расширенных регулярных выражений и извлечение совпадений
На этом этапе вы будете использовать расширенные регулярные выражения для задания альтернатив и повторений, а затем извлечёте только совпавшую подстроку.
Команда grep -E включает такие операторы, как + (один или более символов), ? (ноль или один символ) и | (альтернатива). Найдите полные поля статуса active или pending:
cd /home/labex/project/regex-lab
grep -E '\|(active|pending)\|' contacts.txt
Шаблон, похожий на адрес электронной почты, можно собрать из отдельных частей:
[[:alnum:]._-]+сопоставляется с одним или несколькими допустимыми символами локальной части;@— обычный символ;[[:alnum:].-]+сопоставляется с содержимым домена;\.[[:alpha:]]{2,}сопоставляется с точкой и суффиксом из двух или более букв.
Используйте -o, чтобы выводить только совпавшие подстроки:
grep -Eo '[[:alnum:]._-]+@[[:alnum:].-]+\.[[:alpha:]]{2,}' contacts.txt | tee emails.txt
Пронумеруйте строки с совпадениями и подсчитайте количество извлечённых адресов:
grep -En '\|(active|pending)\|' contacts.txt
wc -l < emails.txt | tr -d ' ' > email-count.txt
cat email-count.txt
Некорректная запись dave_at_example.com не сопоставляется, потому что в ней нет символа @.
Предварительный просмотр преобразований с помощью Sed
На этом этапе вы будете преобразовывать поток с помощью sed, не изменяя входной файл.
Подстановка имеет вид s/pattern/replacement/flags. Замените только первый символ a в каждой строке, а затем замените все строчные a с помощью флага g:
cd /home/labex/project/regex-lab
sed 's/a/A/' contacts.txt
sed 's/a/A/g' contacts.txt
Используйте другой разделитель, если сам текст содержит косые черты или другой разделитель делает команду понятнее. Замените домены адресов электронной почты на redacted.invalid:
sed -E 's#@[[:alnum:].-]+\.[[:alpha:]]{2,}#@redacted.invalid#g' contacts.txt
Адреса sed определяют, к каким строкам применяется команда. Выполните замену статуса только в строках, содержащих точное поле |inactive|:
sed '/|inactive|/s/|inactive|/|disabled|/' contacts.txt | tee contacts-preview.txt
Убедитесь, что в исходном файле по-прежнему содержится inactive:
grep '|inactive|' contacts.txt
Создание очищенного файла с помощью Sed
На этом этапе вы объедините несколько команд sed и сохраните преобразованный поток в новый файл.
Заголовок в services.csv должен остаться без изменений. В строках данных замените warn на warning и добавьте суффикс ms к последнему числовому полю. Параметр -e задаёт несколько команд, а адрес 2,$ ограничивает их применение строками со второй до последней:
cd /home/labex/project/regex-lab
sed -E -e '2,$ s/,warn,/,warning,/' -e '2,$ s/([0-9]+)$/\1ms/' services.csv | tee services-clean.csv
Здесь круглые скобки захватывают последние цифры, а \1 повторно использует это совпадение в замене.
Сравните исходный и новый файлы:
diff -u services.csv services-clean.csv || true
Ненулевой код завершения diff ожидаем, поскольку вывод намеренно изменился; || true позволяет продолжить скопированную последовательность команд.
Выбор полей и агрегация с помощью Awk
На этом этапе вы будете использовать awk, когда задача требует одновременно учитывать структуру полей и выполнять вычисления.
Параметр -F, задаёт запятую в качестве разделителя входных данных. Выведите службу и статус только для строк данных; NR содержит номер текущей записи:
cd /home/labex/project/regex-lab
awk -F, 'NR > 1 {print $1, $2}' services.csv
Выберите строки, в которых числовое третье поле больше 200:
awk -F, 'NR > 1 && $3 > 200 {print $1, $3}' services.csv | tee slow-services.txt
Накопите сумму и количество значений, а затем вычислите среднее в блоке END. printf управляет числовым форматом:
awk -F, 'NR > 1 {sum += $3; count++} END {printf "average_latency=%.1f\n", sum/count}' services.csv | tee latency-summary.txt
Шаблоны Awk определяют, для каких записей выполняется действие; поля, такие как $1 и $3, делают вычисления со структурированными данными понятными.
Итоги
Вы составили шаблоны регулярных выражений с якорями, классами, альтернативами и повторениями; использовали grep для выбора и извлечения; применяли sed для предварительного просмотра и сохранения преобразований; а также использовали awk для выбора и агрегации с учётом полей. В следующем испытании вам нужно будет применить эти идеи без готовой последовательности команд.



