在PowerShell中搜索并替换字符串

时间:2019-03-21 11:33:00

标签: powershell

我需要使用另一个文件中的值来搜索和替换文件中的值。例如,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 个答案:

答案 0 :(得分:2)

您可以使用以下内容,假设 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