Как заменить несколько строк в файле с помощью PowerShell

Зачем заменять несколько строк в PowerShell?
Замена нескольких строк полезна, когда нужно править код, конфиги или текстовые шаблоны в нескольких файлах или в больших блоках файла. Вместо ручной правки по строкам можно составить правило и применить его к целому файлу, что экономит время и снижает вероятность ошибок.
Коротко:
- Подходит для массовой правки конфигураций.
- Удобно при миграции API/путей в коде.
- Полезно для автоматизированных скриптов и CI.
Как заменить одну строку — краткое напоминание
В PowerShell есть оператор -Replace и метод String.Replace. Простой пример в консоли:
PS> \"test\" -Replace \"test\", \"exam\"
Это заменит все вхождения “test” на “exam” в данной строке. Но при работе с файлом и мультилайн-заменой лучше читать весь файл как один блок текста.
Общая стратегия для нескольких строк
- Считать весь файл как одну строку:
- Get-Content <путь> -Raw
- Выполнить замену:
- Использовать оператор -replace (регулярные выражения) или [regex]::Replace
- Записать результат обратно:
- Set-Content <путь> -Value $newText
Пример:
$path = 'C:\\user\\test1.txt'
$text = Get-Content $path -Raw
$newText = $text -replace 'старый блок([\s\S]*?)конец', 'новый блок'
Set-Content $path -Value $newTextЗдесь используется регулярное выражение с захватом многострочного блока. В PowerShell можно применять опцию (?s) или класс символов [\s\S] чтобы точка совпадала с переводами строки.
Пошаговая инструкция
1. Открыть PowerShell
Нажмите клавишу Windows, введите PowerShell и выберите Запуск от имени администратора, если вы редактируете файлы в защищённых папках.

2. Считать файл как одну строку
Пример:
Get-Content C:\\user\\test1.txt -Raw(замечание: укажите правильный путь к файлу)
С помощью ключа -Raw Get-Content возвращает весь файл как одну строку, включая символы перевода строки. Это нужно для многострочных регулярных выражений.
3. Найти соответствия
Можно использовать системный класс [regex] для сложных шаблонов:
[regex]::Matches($text, 'pattern') | Where-Object { $_.Value -like '*c*' }Но чаще будет проще проверить результат визуально:
$text | Select-String -Pattern 'начало.*конец' -AllMatchesSelect-String возвращает совпадения и контекст.
4. Выполнить замену
Два основных варианта:
- Оператор -replace (поддерживает regex и заменяет глобально):
$newText = $text -replace '(?s)oldStart.*?oldEnd', 'replacement'Здесь (?s) включает режим «dot matches newline» — точка совпадает с переводом строки.
- Метод [regex]::Replace:
$newText = [regex]::Replace($text, '(?s)oldStart.*?oldEnd', 'replacement')[regex]::Replace полезен, если нужно настроить RegexOptions (например, IgnoreCase, Multiline).
5. Сохранить изменения
Set-Content C:\\user\\test1.txt -Value $newText -Encoding UTF8Указывайте кодировку при необходимости, чтобы не сломать UTF-8 файлы.
Частые примеры
- Заменить блок между маркёрами:
$path='C:\\user\\test1.txt'
$text=Get-Content $path -Raw
.*?','\nНовый контент\n')
Set-Content $path -Value $text -Encoding UTF8- Заменить несколько отдельных строк через массив шаблонов:
$patterns = @{
'OldValue1' = 'NewValue1'
'OldValue2' = 'NewValue2'
}
$text = Get-Content $path -Raw
foreach($k in $patterns.Keys){
$text = $text -replace [regex]::Escape($k), $patterns[$k]
}
Set-Content $path -Value $textИспользуем [regex]::Escape при точном совпадении, чтобы спецсимволы не трактовались как regex.
Альтернативные подходы
- Использовать -replace в конвейере, если нужно обработать построчно.
- Select-String + ForEach-Object для управления только теми строками, где есть совпадение.
- Использовать внешние утилиты: sed/awk в Git Bash или WSL для привычных Unix-инструментов.
- Для больших файлов можно предпочесть потоковую обработку без чтения всего файла в память.
Пример построчной замены:
Get-Content $path | ForEach-Object { $_ -replace 'pattern', 'replacement' } | Set-Content $pathЭтот вариант читает файл построчно и подходит, если замена не должна пересекать границы строк.
Когда подход не работает
- Если блоки пересекаются сложным образом, простой regex может дать неверный результат.
- Для бинарных файлов текстовые методы не подходят.
- При работе с очень большими файлами чтение в память (-Raw) может вызвать потребление ОЗУ.
- Если важна транзакционная атомарность изменений (откат при ошибке), нужно делать резервную копию перед записью.
Контроль ошибок и безопасность
- Всегда делайте резервную копию: Copy-Item -Path $path -Destination “$path.bak”
- Используйте Try-Catch для перехвата исключений при записи:
try {
Set-Content $path -Value $newText -Encoding UTF8
} catch {
Write-Error "Ошибка записи: $_"
Copy-Item "$path.bak" $path -Force
}- Проверяйте кодировку файлов. Неправильная кодировка может испортить символы.
Чек-лист по ролям
Разработчик:
- Сделать бэкап файла.
- Запустить замену в тестовой ветке или файле.
- Проверить юнит- или интеграционные тесты после изменений.
Системный администратор:
- Проверить права доступа на файл.
- Выполнить замену на тестовом сервере.
- Убедиться в наличии плана отката.
Технический писатель:
- Проверить, что синтаксис и форматирование документации после замены остались корректными.
- Проверить ссылочные идентификаторы и примеры кода.
Критерии приёмки
- Изменения затрагивают только целевой блок, остальные части файла не изменены.
- Файл сохраняется с корректной кодировкой.
- Скрипт успешно проходит прогон в тестовом окружении.
- При откате бэкап восстанавливает исходное состояние.
Приёмка — тест-кейсы
Тест: заменить текст между двумя маркёрами.
- Вход: файл с маркёрами и содержимым.
- Ожидаемый: текст между маркёрами заменён, маркёры на месте.
Тест: замена с учётом регистра.
- Использовать RegexOptions.IgnoreCase или флаг (?i).
Тест: большие файлы.
- Проверить потребление памяти и корректность результата.
Шпаргалка команд
- Считать файл: Get-Content <путь> -Raw
- Построчно: Get-Content <путь>
- Заменить (глобально, regex): $text -replace ‘pattern’,’new’
- Заменить (метод): [regex]::Replace($text,’pattern’,’new’)
- Записать: Set-Content <путь> -Value $text -Encoding UTF8
- Бэкап: Copy-Item -Path $path -Destination “$path.bak”
Частые ошибки и как их исправить
- Результат не изменился: проверьте, соответствует ли regex вашим ожиданиям (включите (?s) или используйте [\s\S]).
- Символы экранирования: используйте [regex]::Escape при точных совпадениях.
- Проблемы с кодировкой: явно указывайте -Encoding при записи.
- Потеря данных: всегда делайте бэкап.
Примеры «не делайте так»
- Не редактируйте важные конфиги на проде без теста.
- Не полагайтесь на один сложный regex для всех случаев — разбейте задачу на шаги.
Альтернативы в среде Windows
- PowerShell Core (pwsh) на кросс-платформенных системах — синтаксис тот же.
- Использовать редакторы с поддержкой массовой замены (VS Code, Notepad++).
- Инструменты управления конфигурацией (Ansible, Chef) для массовых изменений по инфраструктуре.
Итог
PowerShell предоставляет гибкие инструменты для замены нескольких строк в файле. Для большинства задач достаточно прочитать файл -Raw, выполнить замену с помощью -replace или [regex]::Replace и записать результат обратно. Всегда делайте бэкап и тестируйте регулярные выражения на небольших примерах перед применением в продакшене.
Вопросы и свои рабочие примеры можете добавлять в комментариях.
Надеюсь, это поможет вам автоматизировать массовые правки в текстовых файлах с минимальным риском.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone