Поиск и замена строки в PowerShell - PullRequest
0 голосов
/ 21 марта 2019

Мне нужно искать и заменять значения в файле, используя значения из другого файла. Например, A.txt содержит строку со значением LICENSE_KEY_LOC=test_lic, а B.txt содержит строку LICENSE_KEY_LOC= или некоторое значение в ней. Теперь мне нужно заменить всю строку в B.txt значением из A.txt. Я попробовал следующее, но по какой-то причине это не работает.

$filename = "C:\temp\A.txt"

Get-Content $filename | ForEach-Object {
    $val  = $_
    $var  = $_.Split("=")[0]
    $var1 = Write-Host $var'='
    $_ -replace "$var1", "$val"
} | Set-Content C:\temp\B.txt

1 Ответ

2 голосов
/ 21 марта 2019

Вы можете использовать следующее, предполагая, что LICENSE_KEY_LOC = string находится на отдельной строке в файле и существует только один раз:

$filename = Get-Content "c:\temp\A.txt"
$replace = ($filename | Select-String -pattern "(?<=^LICENSE_KEY_LOC=).*$").matches.value
(Get-Content B.txt) -replace "(?<=^LICENSE_KEY_LOC=).*$","$replace" | Set-Content "c:\temp\B.txt"

Для обновления нескольких отдельных ключей / полей в файле вы можете использовать массив и циклически проходить по каждому элементу, обновляя массив $Keys:

$filename = Get-Content "c:\temp\A.txt"
$Keys = @("LICENSE_KEY_LOC","DB_UName","DB_PASSWD")
ForEach ($Key in $Keys) {

    $replace = ($filename | Select-String -pattern "(?<=^$Key=).*$").matches.value
    (Get-Content "c:\temp\B.txt") -replace "(?<=^$Key=).*$","$replace" | Set-Content "c:\temp\B.txt"

}

Вы также можете поместить это в функцию, чтобы сделать ее более модульной:

Function Update-Fields {
  Param(
    [Parameter(Mandatory=$true)]
    [Alias("S")]
    [ValidateScript({Test-Path $_})]
    [string]$SourcePath,
    [Parameter(Mandatory=$true)]
    [Alias("D")]
    [ValidateScript({Test-Path $_})]
    [string]$DestinationPath,
    [Parameter(Mandatory=$true)]
    [string[]]$Fields
  )

$filename = Get-Content $SourcePath
ForEach ($Key in $Fields) {

    $replace = ($filename | Select-String -pattern "(?<=^$Key=).*$").matches.value
    (Get-Content $DestinationPath) -replace "(?<=^$Key=).*$","$replace" | Set-Content $DestinationPath

}
}

Update-Fields -S c:\temp\a.txt -D c:\temp\b.txt -Fields "LICENSE_KEY_LOC","DB_UName","DB_PASSWD"

Пояснение - переменные и регулярные выражения:

  • $replace содержит результат выбора строки, который соответствует шаблону регулярного выражения. Это регистрозависимое совпадение, но вы можете сделать его чувствительным к регистру, используя параметр -CaseSensitive в команде Select-String.
  • (?<=^LICENSE_KEY_LOC=): выполняет регулярное регулярное выражение (без захвата) строки LICENSE_KEY_LOC= в начале строки.
    • (?<=) - положительный взгляд на механизм регулярных выражений
    • ^ отмечает начало строки в каждой строке
    • LICENSE_KEY_LOC= - строковый литерал текста
  • .*$: Соответствует всем символам, кроме перевода строки и возврата каретки, до конца строки в каждой строке
    • .* соответствует нулю или более символов, за исключением перевода строки и возврата каретки, поскольку мы не указали однострочный режим.
    • $ отмечает конец строки в каждой строке
  • -replace "(?<=^LICENSE_KEY_LOC=).*$","$replace" - оператор замены, который выполняет сопоставление регулярному выражению (первый набор двойных кавычек) и заменяет содержимое этого совпадения другими строками или частью захвата регулярного выражения (второй набор двойных кавычек).
    • "$replace" становится значением переменной $replace, так как мы использовали двойные кавычки. Если бы мы использовали одинарные кавычки вокруг переменной, то строка замены была бы буквально $replace.
  • Get-Content "c:\temp\A.txt" получает содержимое файла A.txt. Он читает каждую строку как [string] и сохраняет каждую строку в объекте [array].

Пояснение - Функция:

  • Параметры

    • $SourcePath представляет путь к исходному файлу, который вы хотите прочитать. Я добавил псевдоним S, чтобы при запуске команды можно было использовать переключатель -S. Он проверяет, что путь существует ({Test-Path $_}), прежде чем вносить какие-либо изменения в файлы.

    • $DestinationPath представляет путь к исходному файлу, который вы хотите прочитать. Я добавил псевдоним D, чтобы при запуске команды можно было использовать переключатель -D. Он проверяет, что путь существует ({Test-Path $_}), прежде чем вносить какие-либо изменения в файлы.

    • $Fields - строковый массив. Вы можете ввести одну или несколько строк в формате массива (@("string1","string2") или "string1","string2"). Вы можете создать переменную, которая содержит массив строк, а затем просто использовать переменную в качестве значения параметра, например -Fields $MyArray.

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