Как заменить несколько строк в файле с помощью PowerShell
Я пишу скрипт для настройки файла конфигурации. Я хочу заменить несколько экземпляров строк в этом файле, и я попытался использовать PowerShell для выполнения этой работы.
Он отлично работает для одной замены, но выполнение нескольких замен очень медленно, потому что каждый раз он должен снова анализировать весь файл, и этот файл очень большой. Скрипт выглядит так:
$original_file = 'pathfilename.abc'
$destination_file = 'pathfilename.abc.new'
(Get-Content $original_file) | Foreach-Object {
$_ -replace 'something1', 'something1new'
} | Set-Content $destination_file
Я хочу что-то вроде этого, но я не знаю как это написать:
$original_file = 'pathfilename.abc'
$destination_file = 'pathfilename.abc.new'
(Get-Content $original_file) | Foreach-Object {
$_ -replace 'something1', 'something1aa'
$_ -replace 'something2', 'something2bb'
$_ -replace 'something3', 'something3cc'
$_ -replace 'something4', 'something4dd'
$_ -replace 'something5', 'something5dsf'
$_ -replace 'something6', 'something6dfsfds'
} | Set-Content $destination_file
5 ответов:
один из вариантов-цепочка
-replaceоперации вместе. Элемент`В конце каждой строки экранируется новая строка, в результате чего PowerShell продолжает разбор выражения в следующей строке:$original_file = 'path\filename.abc' $destination_file = 'path\filename.abc.new' (Get-Content $original_file) | Foreach-Object { $_ -replace 'something1', 'something1aa' ` -replace 'something2', 'something2bb' ` -replace 'something3', 'something3cc' ` -replace 'something4', 'something4dd' ` -replace 'something5', 'something5dsf' ` -replace 'something6', 'something6dfsfds' } | Set-Content $destination_fileдругой вариант-назначить промежуточную переменную:
$x = $_ -replace 'something1', 'something1aa' $x = $x -replace 'something2', 'something2bb' ... $x
чтобы сообщение Джорджа Ховарта работало правильно с более чем одной заменой, вам нужно удалить разрыв, назначить выход переменной ($line), а затем вывести переменную:
$lookupTable = @{ 'something1' = 'something1aa' 'something2' = 'something2bb' 'something3' = 'something3cc' 'something4' = 'something4dd' 'something5' = 'something5dsf' 'something6' = 'something6dfsfds' } $original_file = 'path\filename.abc' $destination_file = 'path\filename.abc.new' Get-Content -Path $original_file | ForEach-Object { $line = $_ $lookupTable.GetEnumerator() | ForEach-Object { if ($line -match $_.Key) { $line = $line -replace $_.Key, $_.Value } } $line } | Set-Content -Path $destination_file
предполагая, что вы можете иметь только один
'something1'или'something2'и т. д. в каждой строке можно использовать таблицу поиска:$lookupTable = @{ 'something1' = 'something1aa' 'something2' = 'something2bb' 'something3' = 'something3cc' 'something4' = 'something4dd' 'something5' = 'something5dsf' 'something6' = 'something6dfsfds' } $original_file = 'path\filename.abc' $destination_file = 'path\filename.abc.new' Get-Content -Path $original_file | ForEach-Object { $line = $_ $lookupTable.GetEnumerator() | ForEach-Object { if ($line -match $_.Key) { $line -replace $_.Key, $_.Value break } } } | Set-Content -Path $destination_fileесли вы можете иметь более одного из них, просто удалите
breakнаifзаявление.
с версией 3 PowerShell вы можете связывать вызовы замены вместе:
(Get-Content $sourceFile) | ForEach-Object { $_.replace('something1', 'something1').replace('somethingElse1', 'somethingElse2') } | Set-Content $destinationFile
третий вариант, для конвейерной однострочной является вложить-заменяет:
PS> ("ABC" -replace "B","C") -replace "C","D" ADDи:
PS> ("ABC" -replace "C","D") -replace "B","C" ACDэто сохраняет порядок выполнения, легко читается, и легко помещается в трубопровод. Я предпочитаю использовать скобки для явного контроля, самодокументирования и т. д. Это работает без них, но насколько Вы доверяете этому?
-Replace-это оператор сравнения, который принимает объект и возвращает предположительно измененный объект. Вот почему вы можете складывать или вложите их, как показано выше.
смотрите:
help about_operators
Comments