Как заменить несколько строк в файле с помощью PowerShell - PullRequest
91 голосов
/ 04 августа 2010

Я пишу скрипт для настройки файла конфигурации. Я хочу заменить несколько экземпляров строк в этом файле, и я попытался использовать PowerShell для этой работы.

Он отлично работает для одной замены, но выполнение нескольких замен очень медленное, потому что каждый раз приходится снова анализировать весь файл, и этот файл очень большой. Сценарий выглядит так:

$original_file = 'path\filename.abc'
$destination_file =  'path\filename.abc.new'
(Get-Content $original_file) | Foreach-Object {
    $_ -replace 'something1', 'something1new'
    } | Set-Content $destination_file

Я хочу что-то подобное, но я не знаю, как это написать:

$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

Ответы [ 5 ]

142 голосов
/ 04 августа 2010

Один из вариантов - объединить операции -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
22 голосов
/ 17 февраля 2012

Чтобы почта должным образом работала с более чем одной заменой, вам нужно удалить разрыв, назначить вывод переменной ($ 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
10 голосов
/ 10 января 2016

С версией 3 PowerShell вы можете объединить вызовы на замену:

 (Get-Content $sourceFile) | ForEach-Object {
    $_.replace('something1', 'something1').replace('somethingElse1', 'somethingElse2')
 } | Set-Content $destinationFile
8 голосов
/ 04 августа 2010

Предполагая, что у вас может быть только один '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.

5 голосов
/ 04 января 2014

Третий вариант для конвейерной однострочности заключается во вложении -replaces:

PS> ("ABC" -replace "B","C") -replace "C","D"
ADD

И:

PS> ("ABC" -replace "C","D") -replace "B","C"
ACD

Это сохраняет порядок выполнения, легко читаетсяи аккуратно вписывается в трубопровод.Я предпочитаю использовать скобки для явного контроля, самодокументирования и т. Д. Это работает без них, но насколько вы в это верите?

-Замена - это оператор сравнения, который принимает объект и возвращает предположительно измененный объект.Вот почему вы можете сложить или вложить их, как показано выше.

Пожалуйста, см .:

help about_operators
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...