Автоматизация рутины на C++: пишем скрипты, которые экономят часы

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Ваш C++ — это не только про игры и драйверы

Когда слышишь «C++», часто представляешь себе тяжелую артиллерию: движки Unreal, операционные системы, высоконагруженные серверы. Но есть и другая, не менее полезная сторона — автоматизация задач на C++. Пока коллеги пишут одноразовые баш-скрипты или мучаются с Python-зависимостями, вы можете собрать компактную, быструю утилиту, которая будет работать годами без единого обновления интерпретатора.

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

Почему C++, а не Python или Bash?

У каждого языка своё место. Но есть сценарии, где C++ даёт фору:

  • Скорость выполнения. Если вы обрабатываете терабайты логов — каждая миллисекунда на счету.
  • Отсутствие зависимостей. Один статически скомпилированный бинарник работает на любом Linux/Windows без установки интерпретатора.
  • Типобезопасность. Меньше сюрпризов в рантайме — критично для автоматизации, которая запускается по расписанию.
  • Доступ к системе. Прямая работа с WinAPI, POSIX, реестром, процессами — без прослоек.

Конечно, для быстрого прототипа Python удобнее. Но когда скрипт становится частью CI/CD или production-инфраструктуры, автоматизация на C++ окупается сторицей.

Инструментарий: что нужно знать

Для наших задач не нужен весь C++20. Достаточно базового набора:

  • std::filesystem (C++17) — работа с файлами и папками
  • std::regex — парсинг текста
  • std::fstream / std::stringstream — чтение/запись
  • std::chrono — замеры времени и логирование

Компилируем с флагом -std=c++17 (или /std:c++17 для MSVC).

Пример 1: Пакетное переименование файлов

Представьте: у вас есть папка с фотографиями IMG_001.jpg, IMG_002.jpg … Нужно привести их к формату 2025_01_15_001.jpg. Руками — 10 минут тоскливой работы. Скриптом — 0.2 секунды.

Код

#include <iostream>
#include <filesystem>
#include <regex>
#include <string>

namespace fs = std::filesystem;

int main() {
    std::string dir_path = "./photos";
    std::regex pattern(R"(IMG_(\d+)\.jpg)");
    std::string prefix = "2025_01_15_";

    for (auto &entry : fs::directory_iterator(dir_path)) {
        std::string filename = entry.path().filename().string();
        std::smatch match;

        if (std::regex_match(filename, match, pattern)) {
            std::string new_name = prefix + match[1].str() + ".jpg";
            fs::rename(entry.path(), entry.path().parent_path() / new_name);
            std::cout << "Renamed: " << filename << " -> " << new_name << "\n";
        }
    }
    return 0;
}

Этот пример показывает, как автоматизация задач на C++ с помощью std::filesystem и регулярных выражений решает повседневную проблему за несколько строк. Вы можете легко адаптировать его под свои шаблоны.

Пример 2: Парсинг логов и подсчёт ошибок

Допустим, сервер пишет логи в формате:

2025-01-15 10:23:45 [ERROR] Database connection failed
2025-01-15 10:23:46 [INFO] Retry #1
2025-01-15 10:23:47 [ERROR] Timeout exceeded

Нам нужно собрать статистику: сколько ошибок каждого типа, и вывести топ-5 самых частых сообщений. Bash-однострочник справится, но если логов гигабайты — C++ будет в разы быстрее.

Код

#include <iostream>
#include <fstream>
#include <map>
#include <regex>
#include <vector>
#include <algorithm>

int main(int argc, char* argv[]) {
    if (argc < 2) {
        std::cerr << "Usage: " << argv[0] << " <logfile>\n";
        return 1;
    }

    std::ifstream file(argv[1]);
    std::string line;
    std::map<std::string, int> error_count;
    std::regex error_pattern(R"(\[ERROR\]\s+(.+))");

    while (std::getline(file, line)) {
        std::smatch match;
        if (std::regex_search(line, match, error_pattern)) {
            error_count[match[1].str()]++;
        }
    }

    // Сортируем по убыванию частоты
    std::vector<std::pair<std::string, int>> sorted(error_count.begin(), error_count.end());
    std::sort(sorted.begin(), sorted.end(),
              [](const auto &a, const auto &b) { return a.second > b.second; });

    std::cout << "Top 5 errors:\n";
    for (size_t i = 0; i < std::min(size_t(5), sorted.size()); ++i) {
        std::cout << sorted[i].first << " : " << sorted[i].second << " times\n";
    }
    return 0;
}

Этот инструмент — пример автоматизации тестирования C++ в действии. Вы можете встроить его в CI-пайплайн и получать сводку после каждого запуска тестов.

Пример 3: Генератор отчётов в HTML

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

Код

#include <iostream>
#include <fstream>
#include <filesystem>
#include <regex>
#include <sstream>

namespace fs = std::filesystem;

struct FileStats {
    int lines = 0;
    int functions = 0;
    int comments = 0;
};

FileStats analyze_file(const fs::path &p) {
    std::ifstream file(p);
    std::string line;
    FileStats stats;
    std::regex func_pattern(R"(\w+\s+\w+\s*\([^)]*\)\s*\{?)");
    std::regex comment_pattern(R"(//.*|/\*[\s\S]*?\*/)");

    while (std::get                

Блоги

Рекомендаций по книгам