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

问题描述

我有一个使用以下代码编写的基本PS脚本,我想用该脚本将'version =“ 1.0.0” 替换为 version =“ 19.3.0” ,仅用于其中名称为Sungard的NuGet软件包。下面的脚本为我完成了此任务,但它也清除/删除文件中存在的其他内容,并仅保留以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

解决方法

Set-Content确实做到了其名称的含义 -将文件的内容设置为您通过管道传递给它的任何内容。

因此,当您仅通过管道传输3行文本时,这就是文件中的内容-仅此而已。

由于目标文件是XML文件,因此建议您使用PowerShell的内置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
,
$Output =  (Get-Content "$PathofConfig") | Select-String $String

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...