使用PowerShell替换多个文件的内容

时间:2016-01-12 12:30:12

标签: powershell replace multiple-files

我试图在多个logonscripts中替换某个Line(> 2000 Scripts)。

该脚本以当前形式工作,但它将每个文件写入磁盘,即使没有进行任何更改,但我不想要这种行为。如果进行了更改,它只应写入磁盘。

这就是我已经拥有的:

$varFiles = Get-ChildItem $varPath*.$VarEnding
foreach ($file in $varFiles)
{
    (Get-Content $file) |
    Foreach-Object { $_ -replace [regex]::Escape("$varFind"), "$varReplace" } |
    Set-Content $file   
}

这就是我已经尝试过的,但似乎在管道命令中使用if是不可能的:

$varFiles = Get-ChildItem $varPath*.$VarEnding
foreach ($file in $varFiles)
{
    $control = $file
    (Get-Content $file) |
    Foreach-Object { $_ -replace [regex]::Escape("$varFind"), "$varReplace" } |
    If($control -ne $file){Set-Content $file}   
}

变量$ varPath,$ varEnding,$ varFind和$ varReplace由脚本开头的一些Read-Host命令定义。

我希望你们能帮助我:)。

1 个答案:

答案 0 :(得分:0)

为了简单和快速 - 虽然以内存使用为代价 - 我只是缓存并操作整个输入文件(需要PowerShell v3 +,因为使用了-Raw [1] );由于登录脚本通常很小,这应该是可以接受的:

$varFindEscaped = [regex]::Escape($varFind)
$varReplaceEscaped = $varReplace -replace '\$', '$$$$'

foreach ($file in Get-ChildItem $varPath*$varEnding) {
  $contentBefore = Get-Content -Raw $file
  $contentAfter = $contentBefore -replace $varFindEscaped, $varReplaceEscaped
  if ($contentBefore -ne $contentAfter) {
    Set-Content $file $contentAfter
  }
}
  • 为了提高性能,我已经将-regex操作数转移到了循环之外。
    • 请注意,我还在替换值中转义$个实例,以防止它们被解释为对匹配内容的引用,例如$&引用整场比赛。
  • 请注意,Set-Content默认使用系统的默认代码页而不是UTF-8编码。

[1] 在PS v2中,您可以省略-Raw,将$contentBefore转换为字符串(行)的数组,其元素-replace然后单独运行 < / em>(如OP的方法)。虽然可能稍慢,但它确实具有仅在单独的行上执行替换而不是可能跨多个行的替换的优点。 功能