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

1. Введение
sr.sh — это профессиональный инструмент командной строки для безопасного поиска и замены текста в файлах с поддержкой отката изменений. Скрипт разработан для системных администраторов и разработчиков, которым необходимо выполнять массовые текстовые замены с гарантией возможности восстановления исходного состояния.
Официальный адрес репозитория: https://github.com/paulmann/sr-search-replace
Ключевые возможности:
- Рекурсивный поиск и замена в файлах
- Поддержка сложных шаблонов и специальных символов
- Многоуровневое определение бинарных файлов
- Сессионная система отката с метаданными
- Подробное логирование и статистика
- Режимы dry-run, backup-only и копирования
2. Быстрый старт
# Клонирование репозитория
git clone https://github.com/paulmann/sr-search-replace.git
cd sr-search-replace
# Даем права на выполнение
chmod +x sr.sh
# Простой пример: замена текста в HTML файлах
./sr.sh "*.html" "старый текст" "новый текст"
# Просмотр списка доступных бекапов
./sr.sh --rollback-list
# Откат последней операции
./sr.sh --rollback
# Подробная справка
./sr.sh --help
3. Описание проблемы
3.1 Проблематика стандартных инструментов
Традиционные инструменты поиска и замены (sed, grep, find) имеют ограничения:
- Сложность экранирования специальных символов
- Отсутствие встроенного механизма отката
- Нет различения текстовых и бинарных файлов
- Ограниченная статистика и отчетность
- Проблемы с рекурсивной обработкой
3.2 Решения, предлагаемые sr.sh
- Автоматическое экранирование — скрипт самостоятельно обрабатывает специальные символы в поисковых строках
- Сессионная система отката — каждая операция создает снапшот с метаданными
- Умное определение бинарных файлов — многоуровневая проверка для предотвращения повреждения
- Предсказуемый парсинг аргументов — строгий порядок опций → шаблон → поиск → замена
- Подробная статистика — информация о количестве обработанных файлов и замен
4. Установка
4.1 Базовая установка
# Скачивание скрипта
wget https://raw.githubusercontent.com/paulmann/sr-search-replace/master/sr.sh
chmod +x sr.sh
# Проверка зависимостей
./sr.sh --help # Автоматическая проверка наличия необходимых утилит
4.2 Установка в системный PATH
# Копирование в /usr/local/bin
sudo cp sr.sh /usr/local/bin/sr
sudo chmod +x /usr/local/bin/sr
# Проверка доступности
sr --version
4.3 Зависимости
Обязательные:
bash(версия 4.0+)sedgrepfind
Рекомендуемые (для расширенной функциональности):
file— для точного определения типа файловperl— для сложных заменrealpath— для корректной обработки путей
5. Использование
5.1 Базовый синтаксис
sr [ОПЦИИ] <шаблон_файлов> <искомый_текст> <заменяемый_текст>
Важно: Порядок аргументов строгий — сначала все опции, затем три позиционных аргумента.
5.2 Основные режимы работы
- Режим подстановки (inplace) — замена в исходных файлах с созданием бекапов
- Режим копирования (copy) — создание модифицированных копий в отдельной директории
- Режим только бекапа (backup_only) — создание бекапов без изменения оригиналов
- Тестовый режим (dry-run) — имитация операции без реальных изменений
6. Опции и аргументы
6.1 Основные опции
| Опция | Алиас | Описание |
|---|---|---|
-d, --debug | Включить отладочный вывод | |
-v, --verbose | Подробный вывод (менее детальный, чем debug) | |
-nr, --no-recursive | Обрабатывать только текущую директорию | |
--binary | Разрешить обработку бинарных файлов (ТРЕБУЕТСЯ для бинарных файлов) | |
--dry-run | Показать, что будет изменено, без реальных изменений | |
-h, --help | Показать справку | |
-V, --version | Показать информацию о версии |
6.2 Управление бекапами
| Опция | Алиас | Описание |
|---|---|---|
-nb, --no-backup | Не создавать файлы бекапов | |
-fb, --force-backup | Принудительное создание бекапов, даже если отключено | |
-nbf, --no-backup-folder | Создавать бекапы в той же директории, что и оригинал | |
--max-backups N | Хранить только N последних бекапов (по умолчанию: 10) |
6.3 Система отката
| Опция | Описание |
|---|---|
--rollback | Восстановить из последнего бекапа |
--rollback=BACKUP_DIR | Восстановить из указанной директории бекапа |
--rollback-list | Показать список доступных бекапов с информацией о сессиях |
6.4 Безопасность и фильтрация
| Опция | Алиас | Описание |
|---|---|---|
--binary-method METHOD | Метод определения бинарных файлов: multi_layer, file_only, grep_only | |
--binary-check-size N | Количество байт для проверки на бинарность | |
-xh, --exclude-hidden | Исключить скрытые файлы и директории | |
-xs N, --max-size N | Максимальный размер файла в МБ | |
-xp PATTERNS, --exclude-patterns | Шаблоны файлов для исключения (через пробел) | |
-xd DIRS, --exclude-dirs | Имена директорий для исключения (через пробел) |
6.5 Расширенные опции
| Опция | Алиас | Описание |
|---|---|---|
-md N, --max-depth N | Максимальная глубина рекурсии | |
-delim CHAR, --delimiter CHAR | Пользовательский разделитель для sed | |
-e ENC, --encoding ENC | Кодировка файлов | |
-sd DIR, --search-dir DIR | Директория для поиска | |
-od DIR, --output-dir DIR | Директория для сохранения модифицированных файлов | |
-mode MODE, --replace-mode MODE | Режим замены: inplace, copy, backup_only |
7. Примеры использования
7.1 Базовые примеры
# Замена в HTML файлах
sr "*.html" "старый текст" "новый текст"
# Замена с рекурсией в поддиректориях
sr --verbose "*.js" "var " "let "
# Обработка только текущей директории
sr --no-recursive "config.ini" "debug=true" "debug=false"
7.2 Работа со специальными символами
# Замена путей (автоматическое экранирование слешей)
sr "*.sh" "/old/path" "/new/path"
# Замена с регулярными выражениями
sr "*.txt" "^Start:.*$" "Begin:"
# Работа с JSON файлами
sr --verbose "*.json" '"host": "localhost"' '"host": "production"'
7.3 Обработка бинарных файлов
# Явное разрешение обработки бинарных файлов
sr --binary "*.bin" "search_bytes" "replace_bytes"
# Использование определенного метода детекции
sr --binary-method=multi_layer --binary "data.*" "\x00\x01" "\xFF\xFE"
7.4 Сложные сценарии
# Замена с исключением директорий
sr -xd "node_modules .git" "*.js" "require(" "import "
# Ограничение по размеру файла
sr --max-size=50 "*.log" "ERROR" "WARNING"
# Копирование результатов в отдельную директорию
sr --mode=copy --output-dir=./modified "*.txt" "foo" "bar"
7.5 Откат изменений
# Список доступных бекапов
sr --rollback-list
# Восстановление из последнего бекапа
sr --rollback
# Восстановление из конкретного бекапа
sr --rollback="sr.backup.20231215_143022"
# Предварительный просмотр отката (dry-run)
sr --dry-run --rollback
8. Настройка скрипта (константы)
Скрипт содержит секцию конфигурируемых констант в начале файла:
# ============================================================================
# CONFIGURABLE DEFAULTS - EDIT THESE TO CHANGE SCRIPT BEHAVIOR
# ============================================================================
# Default behavior settings
readonly SESSION_VERSION="6.0.0"
readonly DEFAULT_DEBUG_MODE=false
readonly DEFAULT_RECURSIVE_MODE=true
readonly DEFAULT_DRY_RUN=false
readonly DEFAULT_CREATE_BACKUPS=true
readonly DEFAULT_BACKUP_IN_FOLDER=true
# ... и другие настройки
8.1 Основные настройки
# Поведение по умолчанию
readonly DEFAULT_MAX_DEPTH=100 # Максимальная глубина рекурсии
readonly DEFAULT_MAX_FILE_SIZE_MB=100 # Максимальный размер файла в МБ
readonly DEFAULT_SKIP_BINARY_FILES=true # Пропускать бинарные файлы
readonly DEFAULT_ALLOW_BINARY=false # Требовать явный флаг для бинарных файлов
readonly DEFAULT_PRESERVE_OWNERSHIP=true # Сохранять владельца и права доступа
8.2 Настройки бекапов
# Система бекапов
readonly DEFAULT_BACKUP_PREFIX="sr.backup" # Префикс директории бекапов
readonly DEFAULT_TIMESTAMP_FORMAT="%Y%m%d_%H%M%S" # Формат временной метки
readonly DEFAULT_MAX_BACKUPS=10 # Количество хранимых бекапов
readonly DEFAULT_ROLLBACK_ENABLED=true # Включить систему отката
8.3 Методы определения бинарных файлов
# Алгоритмы детекции
readonly DEFAULT_BINARY_DETECTION_METHOD="multi_layer"
readonly DEFAULT_BINARY_CHECK_SIZE=1024
# Доступные методы:
# - multi_layer: многоуровневая проверка (grep + file utility)
# - file_only: только проверка mime-типа
# - grep_only: только эвристика grep -I
8.4 Настройки исключений
# Паттерны исключения
readonly DEFAULT_EXCLUDE_PATTERNS=".git .svn .hg .DS_Store *.bak *.backup"
readonly DEFAULT_EXCLUDE_DIRS="node_modules __pycache__ .cache .idea .vscode"
8.5 Переопределение через переменные окружения
Все настройки могут быть переопределены через переменные окружения:
# Примеры переопределения
export SR_DEBUG=true
export SR_MAX_DEPTH=50
export SR_EXCLUDE_DIRS="temp logs"
export SR_ALLOW_BINARY=true
./sr.sh "*.txt" "search" "replace"
9. Особенности работы
9.1 Сессионная система
Каждый запуск скрипта создает уникальную сессию с ID и метаданными:
sr.backup.20231215_143022_123456789/
├── .sr_session_metadata # Метаданные сессии
├── .sr_modified_files # Список измененных файлов
├── .sr_file_info # Детальная информация
└── [файлы бекапов] # Копии измененных файлов
9.2 Многоуровневое определение бинарных файлов
Алгоритм multi_layer (по умолчанию):
- Уровень 1: Быстрая проверка размера (пустые файлы считаются текстовыми)
- Уровень 2: Эвристика
grep -Iпо первым N байтам - Уровень 3: Верификация через
file --mime-type(если доступен)
9.3 Предсказуемый парсинг аргументов
Скрипт использует строгий порядок парсинга:
- Все опции (с любым количеством дефисов)
- Шаблон файлов
- Искомая строка
- Заменяемая строка
# Правильно: опции ДО позиционных аргументов
sr --verbose --binary "*.txt" "search" "replace"
# Неправильно: опции ПОСЛЕ позиционных аргументов
sr "*.txt" "search" "replace" --verbose # ОШИБКА!
9.4 Обработка shell-экспансий
Скрипт автоматически определяет, когда shell расширил glob-паттерн:
# Shell расширяет *.html до file1.html file2.html
sr file1.html file2.html "search" "replace"
# Скрипт определит это и обработает явный список файлов
9.5 Сохранение метаданных файлов
При включенной опции --preserve-ownership (по умолчанию):
- Сохраняются права доступа (chmod)
- Сохраняется владелец и группа (chown)
- Сохраняется время модификации (если файл не изменен)
10. Восстановление (откат) изменений
10.1 Автоматическое создание бекапов
При каждом запуске (если не отключено) создается директория бекапа:
- Имя:
sr.backup.ГГГГММДД_ЧЧММСС_НАНОСЕКУНДЫ - Содержит полные копии всех измененных файлов
- Включает метаданные для точного восстановления
10.2 Процесс восстановления
# Просмотр доступных бекапов
sr --rollback-list
# Восстановление последней операции
sr --rollback
# Восстановление конкретной сессии
sr --rollback="sr.backup.20231215_143022_123456789"
10.3 Что восстанавливается
- Содержимое файлов — точные копии из бекапа
- Права доступа — если были сохранены в оригинальной сессии
- Владелец и группа — если скрипт запущен с достаточными привилегиями
- Иерархия директорий — автоматическое создание недостающих директорий
10.4 Интерактивное подтверждение
Перед восстановлением скрипт показывает:
- Список файлов для восстановления
- Размер каждого файла
- Информацию о сессии
- Запрашивает подтверждение (таймаут 30 секунд)
11. Устранение неисправностей
11.1 Коды возврата
| Код | Описание |
|---|---|
| 0 | Успешное выполнение |
| 1 | Неверные аргументы или недостаточно прав |
| 2 | Файлы, соответствующие шаблону, не найдены |
| 3 | Искомая строка не найдена ни в одном файле |
| 4 | Критическая ошибка во время обработки |
| 5 | Не удалось создать бекап |
| 6 | Обнаружен бинарный файл без флага --binary |
| 7 | Ошибка отката |
11.2 Режимы отладки
# Включение отладочного вывода
sr --debug "*.txt" "search" "replace"
# Только verbose режим
sr --verbose "*.txt" "search" "replace"
# Dry-run для тестирования
sr --dry-run --verbose "*.txt" "search" "replace"
11.3 Частые проблемы и решения
Проблема: «Binary file detected without —binary flag»
Решение: Используйте --binary для явного разрешения или проверьте, не является ли файл действительно бинарным.
Проблема: «No files found matching pattern»
Решение:
- Убедитесь, что шаблон заключен в кавычки:
"*.html" - Проверьте текущую директорию:
sr --search-dir=/path "*.txt" ... - Используйте
--debugдля просмотра процесса поиска
Проблема: «Permission denied»
Решение:
- Запустите с sudo (если требуется изменение системных файлов)
- Используйте
--no-preserve-ownershipдля игнорирования прав доступа - Проверьте права на запись в директорию бекапов
11.4 Логи и диагностика
# Временные файлы отладки
/tmp/sr_rollback_debug_*.log # Логи отката
/tmp/sr_filelist_* # Временные списки файлов
/tmp/sr_temp_* # Временные файлы обработки
12. Безопасность
12.1 Меры предосторожности
- Бинарные файлы по умолчанию пропускаются — требуется явный флаг
--binary - Исключение бекап-директорий — автоматическое исключение директорий
sr.backup.* - Проверка путей — защита от path traversal атак
- Подтверждение деструктивных операций — запрос подтверждения для отката
- Ограничение на размер файлов — предотвращение обработки огромных файлов
12.2 Рекомендации по использованию в production
# Всегда используйте dry-run для проверки
sr --dry-run --verbose "*.conf" "old_value" "new_value"
# Создавайте явные бекапы перед массовыми заменами
sr --mode=backup_only "*.php" "mysql_" "mysqli_"
# Используйте ограничения по размеру и глубине
sr --max-size=10 --max-depth=5 "*.log" "pattern" "replacement"
# Работайте в изолированной директории копий
sr --mode=copy --output-dir=./test_changes "*.js" "var " "let "
13. Советы и лучшие практики
13.1 Эффективное использование
- Используйте dry-run для предварительной проверки
sr --dry-run --verbose "*.html" "old" "new"
- Явно указывайте директорию поиска
sr --search-dir=/var/www "*.php" "deprecated" "current"
- Используйте режим копирования для сложных изменений
sr --mode=copy --output-dir=./modified "*.json" '"ip":".*?"' '"ip":"redacted"'
- Сохраняйте историю бекапов
# Увеличьте количество хранимых бекапов
export SR_MAX_BACKUPS=30
13.2 Интеграция с другими инструментами
# Использование в комбинации с find
find /var/log -name "*.log" -exec sr --verbose {} "ERROR" "WARNING" \;
# Пакетная обработка через xargs
echo "file1.txt file2.txt file3.txt" | xargs sr --verbose "foo" "bar"
# Интеграция в скрипты деплоя
#!/bin/bash
set -e
sr --dry-run "*.env" "localhost" "production-server"
sr --verbose "*.env" "localhost" "production-server"
13.3 Производительность
- Для большого количества файлов используйте
--binary-method=grep_only - При работе в глубоких иерархиях ограничьте
--max-depth - Используйте
--exclude-dirsдля исключения ненужных директорий - Для бинарных файлов задавайте явный
--binary-check-size
14. Заключение
sr.sh представляет собой профессиональный инструмент для безопасного поиска и замены текста в файлах. Сочетание мощных возможностей, системы отката изменений и детальной настраиваемости делает его идеальным выбором для системных администраторов и разработчиков, работающих с большим количеством текстовых данных.
Ключевые преимущества:
- ✅ Безопасность — многоуровневая защита от ошибок
- ✅ Гибкость — поддержка сложных сценариев использования
- ✅ Надежность — полная система отката изменений
- ✅ Удобство — подробная статистика и логирование
- ✅ Производительность — оптимизированные алгоритмы работы
Скрипт постоянно развивается и поддерживается. Актуальные версии и документация доступны в репозитории проекта.
Лицензия: MIT
Редакция документации: Декабрь 2025
Версия скрипта: 6.0.0
При использовании скрипта в production-окружении всегда предварительно тестируйте изменения в dry-run режиме.