Ответ 1
tl; dr (PSv5+; см. нижнюю часть для более старых версий):
(Get-Content webtemp.config) -replace "database=myDb;","database=newDb;" -join "'n" |
Set-Content -NoNewline -Force web1.config
Примечание. Замените "'n"
на "'r'n"
если вы хотите, чтобы "'r'n"
строки в стиле CRLF в стиле Windows, а не в "'r'n"
строки только в LF в стиле Unix (PowerShell и многие утилиты могут обрабатывать оба варианта).
В PSv5+ Set-Content
поддерживает переключатель -NoNewline
, который инструктирует Set-Content
не добавлять новую строку (разрыв строки) после каждого входного объекта. То же самое относится и к командлетам Add-Content
и Out-File
.
Другими словами: Set-Content -NoNewline
напрямую объединяет строковые представления всех своих входных объектов:
> 'one', 'two' | Set-Content -NoNewline tmp.txt; Get-Content tmp.txt
onetwo
Если то, что вы передаете в Set-Content -NoNewline
является отдельной строкой, в которой уже есть встроенные символы новой строки, вы можете использовать ее как есть и получить желаемый результат:
> "one'ntwo" | Set-Content -NoNewline tmp.txt; "$(Get-Content -Raw tmp.txt)?"
one
two?
Обратите внимание, что Get-Content -Raw
читает файл в целом, как есть (кроме декодирования символов) и тот факт, что ?
появляется сразу после two
что означает, что в файле нет завершающего символа новой строки.
В вашем случае, поскольку вы обрабатываете входные строки одну за другой (через Get-Content
без -Raw
) и, следовательно, -Raw
массив строк (строк), вы должны сначала объединить их с новой строкой в качестве разделителя - только между строками - и передать результат в Set-Content -NoNewline
, как показано вверху; вот упрощенный пример:
> ('one', 'two') -join "'n" | Set-Content -NoNewline tmp.txt; "$(Get-Content -Raw tmp.txt)?"
one
two?
'one', 'two'
- это двухэлементный строковый массив, который заменяет вашу построчную команду обработки.
Кодировка примечания:
В Windows PowerShell Set-Content
создает файлы "ANSI" -encoded по умолчанию на основе устаревшей однобайтовой кодовой страницы вашей системы.
Для явного управления кодировкой используйте параметр -Encoding
.
В PSv4- необходимо решение, использующее .NET Framework:
> [System.IO.File]::WriteAllText('tmp.txt', ('one', 'two') -join "'n"); "$(Get-Content -Raw tmp.txt)?"
one
two?
Обратите внимание, что [System.IO.File]::WriteAllText()
, при отсутствии аргумента кодирования, по умолчанию использует UTF-8 без спецификации.
При необходимости [System.Text.Encoding]
требуемый экземпляр кодировки [System.Text.Encoding]
в качестве 3-го аргумента.