为什么 Set-Content 命令会清理包配置文件,然后替换 Package.config 文件中的内容?

Why is the Set-Content Command Cleaning the Package Config File and then Replacing the Content in the Package.config file?

我有一个基本的 PS 脚本,用下面的代码编写,我想用这个脚本将 'version="1.0.0" 替换为 [= package.config 文件中的 16=]version="19.3.0" 仅适用于其中名称为 Sungard 的 NuGet 包。下面的脚本为我做了这个,但它也 clears\remove 文件中存在的其他内容,并且只保留以 Sungard 开头的 NuGet 包。我也尝试使用 Out-File 命令,结果是一样的。

知道为什么它在执行脚本后删除文件的其他内容而不是仅仅替换所要求的内容吗? 如何仅替换 package.config 文件中以名称 Sungard 开头的 Nuget 包的版本?

$PathofConfig = "$PSScriptRoot\packages.config"
$String='SunGard*'

$Output =  (Get-Content "$PathofConfig") | Select-String $String 
Write-Host $Output
$Output -replace 'version="1.0.0"','version="19.3.0"' | Set-Content $PathofConfig
$Output =  (Get-Content "$PathofConfig") | Select-String $String

上面的代码行表示您只 select 匹配您提供的模式的字符串。因此,最初您获得了整个文件的内容,但只将该文件的匹配部分保存到一个变量中。 您可以使用 ForEach 循环来实现您所需要的。

(Get-Content '$PathofConfig') | Foreach-Object {
      if($_ | Select-string -Pattern "$String"){$_ -replace 'version="1.0.0"', 'version="19.3.0"'}
      else {$_}
      } | Set-Content $PathofConfig

Set-Content 正如它的名字所暗示的那样 - 它将文件的内容设置为您通过管道传递给它的任何内容。

因此,当您仅向其中输入 3 行文本时,这就是文件中的最终结果 - 仅此而已。

由于您的目标文件是 XML 文件,我建议使用 PowerShell 的 built-in XML 解析功能来修改它:

$config = [xml]::new()
$config.Load($PathofConfig)

foreach($package in $config.packages.package){
  if($package.id -like $string -and $package.version -eq '1.0.0'){
    $package.version = '19.3.0'
  }
}

$config.Save($PathofConfig)

如果您坚持使用正则表达式执行此操作,请确保前缀测试是 -replace 操作的一部分:

$content = Get-Content $PathofConfig

# need to translate the pattern to its regex equivalent before we can use it
$string = 'Sunguard.*'

$content -replace "(?=${string})version=`"1.0.0`"",'version="19.3.0"' |Set-Content $PathofConfig