用PowerShell替换多个文件的内容

用PowerShell替换多个文件的内容,powershell,replace,Powershell,Replace,我正在尝试替换多个logonscripts(>2000个脚本)中的某一行 脚本以当前形式工作,但它会将每个文件写入磁盘,即使没有进行任何更改,但我不希望出现这种行为。它只应在进行更改时写入磁盘 这是我已经拥有的: $varFiles = Get-ChildItem $varPath*.$VarEnding foreach ($file in $varFiles) { (Get-Content $file) | Foreach-Object { $_ -replace [regex

我正在尝试替换多个logonscripts(>2000个脚本)中的某一行

脚本以当前形式工作,但它会将每个文件写入磁盘,即使没有进行任何更改,但我不希望出现这种行为。它只应在进行更改时写入磁盘

这是我已经拥有的:

$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由脚本开头的几个读取主机命令定义


我希望你们能帮助我:)

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

$varFindEscaped=[regex]::转义($varFind)
$varreplaceeved=$varReplace-replace'\$','$$$$'
foreach($Get ChildItem中的文件$varPath*$varEnding){
$contentBefore=获取内容-原始$file
$contentAfter=$contentBefore-替换$varFindEscaped,$varReplaceEscaped
如果($contentBefore-ne$contentAfter){
设置内容$file$contentAfter
}
}
  • 为了提高性能,我将
    -regex
    操作数的转义移到了循环之外。
    • 请注意,我还在替换值中转义
      $
      实例,以防止它们被解释为对匹配内容的引用,例如
      $&
      以引用整个匹配
  • 请注意,
    设置内容
    默认情况下使用系统的默认代码页,而不是UTF-8编码

[1] 在PS v2中,您可以省略
-Raw
,它将
$contentBefore
转换为一个字符串(行)数组,其元素
-replace
然后单独操作(如OP的方法)。虽然可能稍微慢一点,但它的优点是只在单个行上执行替换,而不是可能跨多个行执行替换。

为了简单和快速,尽管以牺牲内存使用为代价,我还是简单地缓存和操作整个输入文件(由于使用了
-Raw
[1]);由于登录脚本通常很小,因此这应该是可以接受的:

$varFindEscaped=[regex]::转义($varFind)
$varreplaceeved=$varReplace-replace'\$','$$$$'
foreach($Get ChildItem中的文件$varPath*$varEnding){
$contentBefore=获取内容-原始$file
$contentAfter=$contentBefore-替换$varFindEscaped,$varReplaceEscaped
如果($contentBefore-ne$contentAfter){
设置内容$file$contentAfter
}
}
  • 为了提高性能,我将
    -regex
    操作数的转义移到了循环之外。
    • 请注意,我还在替换值中转义
      $
      实例,以防止它们被解释为对匹配内容的引用,例如
      $&
      以引用整个匹配
  • 请注意,
    设置内容
    默认情况下使用系统的默认代码页,而不是UTF-8编码

[1] 在PS v2中,您可以省略
-Raw
,它将
$contentBefore
转换为一个字符串(行)数组,其元素
-replace
然后单独操作(如OP的方法)。虽然可能稍微慢一点,但它的优点是只在单个行上执行替换,而不是可能跨多个行执行替换。

谢谢您的建议,但我使用的是PS v2,因此很遗憾,这一版本对我不适用。你有办法在PS v2中实现这一点吗?我刚刚从Get Content中删除了-raw属性,以便在PS v2上使用它,它在我的10个测试文件中发挥了巨大的作用。非常感谢!:)@LöwäCent很高兴听到这个消息;我在答案中添加了一个注释re
-Raw
。RAM和CPU使用不是我的问题。更让我担心的是磁盘使用率和DC复制(因为它会在20多个站点上的大约50个DC上复制2000多个Logonscripts),所以这完全适合我。@LöwäCent:明白了,谢谢。老实说,我没有运行性能测试,所以在上面的代码中使用
-Raw
和不使用它在性能上很可能没有什么区别。谢谢你的建议,但我使用的是PS v2,所以很遗憾,这一个对我不起作用。你有办法在PS v2中实现这一点吗?我刚刚从Get Content中删除了-raw属性,以便在PS v2上使用它,它在我的10个测试文件中发挥了巨大的作用。非常感谢!:)@LöwäCent很高兴听到这个消息;我在答案中添加了一个注释re
-Raw
。RAM和CPU使用不是我的问题。更让我担心的是磁盘使用率和DC复制(因为它会在20多个站点上的大约50个DC上复制2000多个Logonscripts),所以这完全适合我。@LöwäCent:明白了,谢谢。老实说,我还没有运行性能测试,所以在上面的代码中使用
-Raw
和不使用它在性能上可能没有什么区别。