0Pricing
DevOps Bootcamp · Урок

Шаблоны, диапазоны и блоки BEGIN/END

Фильтруйте записи с помощью условных шаблонов и формируйте заголовки и итоги, используя блоки BEGIN и END

«Шаблоны, диапазоны и блоки BEGIN/END» — бесплатный урок DevOps Bootcamp на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения DevOps Bootcamp, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс DevOps Bootcamp содержит 4 уроков всего.

Что такое шаблоны awk

В awk шаблон — это условие, которое определяет, будет ли блок действий выполнен для данной входной строки. Общая форма записи:

awk 'pattern { action }' file

Если шаблон соответствует текущей записи, выполняется действие. Если действие не задано, awk по умолчанию выводит всю строку. Шаблоны могут быть:

  • Регулярными выражениями — /regex/
  • Операциями сравнения — $3 > 100
  • Составными выражениями — $1 == "ERROR" && $4 > 500
  • Диапазонными шаблонами — /start/,/end/
  • Специальными шаблонами — BEGIN и END

Понимание шаблонов открывает путь к использованию awk как мощного фильтра данных, а не просто средства вывода столбцов.

Регулярные выражения для фильтрации строк

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

Ниже мы фильтруем файл в стиле /var/log/syslog, чтобы показать только строки, содержащие слово ERROR:

#!/usr/bin/env bash
# Simulate a log file and filter ERROR lines
log=$(cat <<'EOF'
2026-06-11 08:01:22 INFO  service started
2026-06-11 08:02:05 ERROR disk quota exceeded on /dev/sda1
2026-06-11 08:02:44 WARN  memory usage at 80%
2026-06-11 08:03:10 ERROR connection timeout to 10.0.0.5
2026-06-11 08:03:55 INFO  backup completed
EOF
)

echo "=== ERROR lines only ==="
echo "$log" | awk '/ERROR/ { print NR": "$0 }'

Отрицательные и составные шаблоны

Добавьте перед регулярным выражением !, чтобы инвертировать условие и выбрать строки, которые не содержат шаблон. Объединяйте несколько условий с помощью && (AND) или || (OR), чтобы точно управлять фильтрацией.

  • !/DEBUG/ — пропускать строки отладки
  • $3 > 500 && $5 == "POST" — крупные запросы POST
  • /WARN/ || /ERROR/ — любой из двух уровней серьёзности

Приведённый ниже пример разбирает упрощённый журнал доступа и выводит только запросы POST с размером ответа более 1000 байт:

#!/usr/bin/env bash
access=$(cat <<'EOF'
10.0.0.1 GET  /api/ping     200  48
10.0.0.2 POST /api/upload   201  2048
10.0.0.3 GET  /api/users    200  512
10.0.0.4 POST /api/data     200  3500
10.0.0.5 POST /api/health   200  60
EOF
)

echo "Large POST requests (>1000 bytes):"
echo "$access" | awk '$2 == "POST" && $5 > 1000 { print $1, $3, "size="$5 }'

Диапазонные шаблоны: /start/,/end/

Диапазонный шаблон выбирает непрерывный блок записей — от строки, соответствующей /start/, до строки, соответствующей /end/, включая обе строки. Синтаксис:

awk '/start/,/end/ { action }' file

Важно знать следующее:

  • Диапазон активируется на первой строке, соответствующей /start/, и деактивируется после первой последующей строки, соответствующей /end/.
  • Если /end/ ни разу не встретится, диапазон останется активным до EOF.
  • Несколько непересекающихся диапазонов в одном файле обрабатываются независимо друг от друга.

Поэтому диапазонные шаблоны идеально подходят для извлечения отмеченных разделов из конфигурационных файлов, журналов с заголовками-разделителями или многочастных отчётов.

Извлечение разделов с помощью диапазонных шаблонов

Рассмотрим конфигурацию сервера с несколькими именованными разделами, ограниченными заголовками [section]. Нам нужны только строки внутри [database]:

#!/usr/bin/env bash
config=$(cat <<'EOF'
[server]
host = 0.0.0.0
port = 8080

[database]
host = 127.0.0.1
port = 5432
name = appdb
user = admin

[cache]
host = 127.0.0.1
port = 6379
EOF
)

echo "=== [database] section ==="
echo "$config" | awk '/\[database\]/,/^\[/' \
  | awk 'NR > 1 && !/^\[/ && NF'

Блок BEGIN

Блок BEGIN выполняется один раз до чтения любых входных данных. Он идеально подходит для следующих задач:

  • Вывода заголовка отчёта
  • Инициализации переменных и счётчиков
  • Настройки разделителя полей (FS) и других встроенных переменных
  • Запуска автономных программ awk, которым не нужны входные данные

Синтаксис:

awk 'BEGIN { setup } pattern { action }' file

Задание FS в BEGIN — удобная альтернатива флагу -F, особенно при написании программ с несколькими правилами, где логика разделения находится внутри скрипта.

#!/usr/bin/env bash
csv=$(cat <<'EOF'
alice,engineering,95000
bob,marketing,72000
carol,engineering,105000
dave,hr,68000
EOF
)

echo "$csv" | awk 'BEGIN {
  FS = ","
  printf "%-10s %-15s %10s\n", "Name", "Department", "Salary"
  print "--------------------------------------------"
}'

Блок END

Блок END выполняется один раз после обработки последней записи. Это естественное место для следующих действий:

  • Вывода итогов, средних значений и сводок, накопленных во время обработки
  • Сброса данных или закрытия выходных файлов
  • Вывода строк нижнего колонтитула в форматированных отчётах

Переменные, заданные во время обработки основных правил, по-прежнему доступны внутри END — так реализуются текущие итоги. В приведённом ниже примере суммируются значения зарплат из CSV, а итог выводится в нижнем колонтитуле:

#!/usr/bin/env bash
csv=$(cat <<'EOF'
alice,engineering,95000
bob,marketing,72000
carol,engineering,105000
dave,hr,68000
EOF
)

echo "$csv" | awk -F',' '
  { total += $3; count++ }
  END { printf "Employees: %d  Total payroll: $%d\n", count, total }
'

Объединение BEGIN, правил и END

Настоящая мощь awk раскрывается, когда все три блока объединяются в одну автономную программу awk, которая выводит заголовок, обрабатывает каждую запись и выводит сводку. Этот шаблон лежит в основе конвейеров подготовки отчётов в shell-скриптах.

Ниже приведён полный генератор отчётов, который читает CSV с веб-запросами, выводит сведения по каждой строке и в конце подсчитывает количество запросов, выполнявшихся более 1 секунды:

#!/usr/bin/env bash
data=$(cat <<'EOF'
/api/ping,0.03
/api/users,1.45
/api/login,0.88
/api/upload,2.10
/api/health,0.02
/api/report,1.73
EOF
)

echo "$data" | awk -F',' '
BEGIN {
  printf "%-20s %10s %s\n", "Endpoint", "Latency(s)", "Status"
  print "--------------------------------------"
}
{
  status = ($2 > 1.0) ? "SLOW" : "OK"
  if (status == "SLOW") slow++
  printf "%-20s %10s %s\n", $1, $2, status
}
END {
  print "--------------------------------------"
  printf "Slow requests: %d / %d\n", slow, NR
}
'

Использование BEGIN для задания OFS и ORS

Две часто упускаемые из виду выходные переменные можно удобно задать в BEGIN:

  • OFS (разделитель выходных полей) — вставляется между полями при перестроении записи с помощью $1=$1 или при использовании print $1, $2
  • ORS (разделитель выходных записей) — добавляется после каждого вызова print (по умолчанию это \n)

Задание OFS="," позволяет за один проход преобразовать TSV в CSV без конкатенации строк. Изменение ORS на "\n---\n" автоматически добавляет разделители между записями.

#!/usr/bin/env bash
# Convert whitespace-delimited data to CSV with a header
data=$(cat <<'EOF'
alice   engineering  95000
bob     marketing    72000
carol   engineering  105000
EOF
)

echo "$data" | awk 'BEGIN { OFS=","; print "name,dept,salary" }
{ $1=$1; print }'

Практический диапазонный шаблон: окна инцидентов в журналах

Диапазонные шаблоны особенно полезны при анализе рабочих журналов. Распространённая задача — извлечь все строки журнала между началом и концом инцидента, обозначенными специальными сообщениями, например INCIDENT START и INCIDENT END.

В приведённом ниже примере awk извлекает только строки внутри окна инцидента и подсчитывает содержащиеся в нём события ERROR, объединяя диапазонный шаблон с накопителем и итоговой сводкой в END:

#!/usr/bin/env bash
log=$(cat <<'EOF'
08:00:01 INFO  Normal operation
08:01:00 INFO  INCIDENT START: disk pressure detected
08:01:05 ERROR write failed on /dev/sda1
08:01:09 ERROR inode table corruption
08:01:14 WARN  remounting read-only
08:01:22 INFO  INCIDENT END: disk replaced
08:02:00 INFO  Normal operation resumed
EOF
)

echo "$log" | awk '
/INCIDENT START/,/INCIDENT END/ {
  print
  if (/ERROR/) errors++
}
END { print "Errors during incident:", errors+0 }
'

Пропуск строк-разделителей в диапазоне

По умолчанию диапазонные шаблоны включают сами строки, соответствующие /start/ и /end/. Чтобы пропустить эти строки-разделители и оставить только содержимое между ними, ограничьте действие отрицанием или переменной-флагом:

  • Подход с отрицанием: /start/,/end/ { if (!/start/ && !/end/) print }
  • Подход с флагом: вручную задавать переменной значение 1 для /start/ и 0 для /end/

Подход с флагом надёжнее, если текст разделителя может также встречаться в содержимом:

#!/usr/bin/env bash
doc=$(cat <<'EOF'
## preamble
some intro text
## BEGIN_REPORT
row1: alpha 100
row2: beta  200
row3: gamma 150
## END_REPORT
## appendix
EOF
)

echo "$doc" | awk '
/## BEGIN_REPORT/ { capture=1; next }
/## END_REPORT/   { capture=0 }
capture           { print }
'

Проверка знаний: поведение блока BEGIN

Проверьте, как хорошо Вы понимаете взаимодействие блоков BEGIN и END с обработкой входных данных в awk.

Итоги урока: шаблоны, диапазоны и BEGIN/END

На этом уроке Вы освоили три наиболее мощные структурные возможности программ awk:

  • Шаблоны — регулярные выражения (/ERROR/), операции сравнения ($3 > 1000), отрицательные условия (!/DEBUG/) и составные условия (&&, ||) определяют, какие записи вызывают действие, без необходимости в явных операторах if.
  • Диапазонные шаблоны (/start/,/end/) выбирают непрерывные блоки записей и идеально подходят для извлечения окон инцидентов из журналов, разделов конфигурации и фрагментов отчётов. Используйте переменную-флаг (next + логическое значение), если требуется исключить сами строки-разделители.
  • Блок BEGIN — выполняется один раз до чтения входных данных; идеально подходит для задания FS, OFS и ORS, инициализации счётчиков и вывода заголовков отчётов.
  • Блок END — выполняется один раз после всех входных данных; это подходящее место для вывода итогов, средних значений и нижних колонтитулов с использованием переменных, накопленных в основных правилах.

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

Часто задаваемые вопросы

Урок «Шаблоны, диапазоны и блоки BEGIN/END» бесплатный?

Да — полный текст урока «Шаблоны, диапазоны и блоки BEGIN/END» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс DevOps Bootcamp, подпишись на CoddyKit PRO. Курс DevOps Bootcamp содержит 4 уроков всего.

Чему я научусь в уроке «Шаблоны, диапазоны и блоки BEGIN/END»?

Фильтруйте записи с помощью условных шаблонов и формируйте заголовки и итоги, используя блоки BEGIN и END Ты практикуешь DevOps Bootcamp с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать DevOps Bootcamp?

Предыдущий опыт не требуется. DevOps Bootcamp на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Шаблоны, диапазоны и блоки BEGIN/END»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке DevOps Bootcamp?

Да. Каждый урок DevOps Bootcamp включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Записи, поля и пользовательские разделители в awk
  2. Шаблоны, диапазоны и блоки BEGIN/END
  3. Агрегация и группировка с массивами awk
  4. Функции awk, форматирование printf и создание отчётов
← Назад к DevOps Bootcamp