更换管道导致行重复

时间:2016-01-28 03:46:27

标签: powershell

我有一个脚本,我需要替换几行。第一个替换正常,但第二个是擦除我的文件并多次重复该行。

我的代码

(get-content $($sr)) -replace 'remoteapplicationname:s:SHAREDAPP',"remoteapplicationcmdline:s:$($sa)" | Out-File $($sr)
(get-content $($sr)) -replace 'remoteapplicationprogram:s:||SHAREDAPP',"remoteapplicationprogram:s:||$($sa)" | Out-File $($sr)

第一个替换工作完美。第二个是造成这个:

  

remoteapplicationprogram:S:|| stagaredrremoteapplicationprogram:S:|| stagarederemoteapplicationprogram:S:|| stagareddremoteapplicationprogram:S:|| stagarediremoteapplicationprogram:S:|| stagaredrremoteapplicationprogram:S:|| stagarederemoteapplicationprogram:S:|| stagaredcremoteapplicationprogram:S:| | stagaredtremoteapplicationprogram:S:|| stagaredcremoteapplicationprogram:S:|| stagaredlremoteapplicationprogram:S:|| stagarediremoteapplicationprogram:S:|| stagaredpremoteapplicationprogram:S:|| stagaredbremoteapplicationprogram:S:|| stagaredoremoteapplicationprogram:S:|| stagaredaremoteapplicationprogram:S:|| stagaredrremoteapplicationprogram :S:|| stagareddremoteapplicationprogram:S:|| stagared:remoteapplicationprogram:S:|| stagarediremoteapplicationprogram:S:|| stagared:remoteapplicationprogram:S:|| stagared1remoteapplicationprogram:S:|| stagared   等...

这是因为||?如果是这样,我该如何解决它?

谢谢!

1 个答案:

答案 0 :(得分:3)

首先,您应该为变量使用稍微更有意义的名称。特别是如果您希望其他人查看您的代码。

您的问题的要点是-replace支持正则表达式(正则表达式),并且您的模式字符串中有正则表达式控制字符。请考虑以下简单示例,并注意找到替换字符串的所有位置:

PS C:\Users\Matt> "ABCD" -replace "||", "bagel"
bagelAbagelBbagelCbagelDbagel

-replace也是一个数组运算符,因此它适用于输入文件的每一行,这很好。为简单起见,如果您不使用正则表达式,则应该考虑使用字符串方法.Replace(),但它区分大小写,因此可能不太理想。所以让我们以最简单的方式逃避那些控制角色:

$patternOne = [regex]::Escape('remoteapplicationname:s:SHAREDAPP')
$patternTwo = [regex]::Escape('remoteapplicationprogram:s:||SHAREDAPP')


(get-content $sr) -replace $patternOne, "remoteapplicationcmdline:s:$sa" | Out-File $($sr)
(get-content $sr) -replace $patternTwo, "remoteapplicationprogram:s:||$sa" | Out-File $($sr)

现在我们将两种模式匹配,就像你写的一样。在控制台上运行$patternTwo以查看更改内容的内容! $patternOne,如上所述,其中没有正则表达式控制字符,但如果您只是期望简单匹配,则使用escape方法并没有什么坏处。

除了指出的主要问题外,还有一些可以在这里解决的冗余和误解。我假设您正在更新源文件以替换所有出现的字符串,是吗?好吧,您不需要两次读取文件,因为您可以链接-replace

$patternOne = [regex]::Escape('remoteapplicationname:s:SHAREDAPP')
$patternTwo = [regex]::Escape('remoteapplicationprogram:s:||SHAREDAPP')

(get-content $sr) -replace $patternOne, "remoteapplicationcmdline:s:$sa" -replace $patternTwo, "remoteapplicationprogram:s:||$sa" | 
        Set-Content $sr

也许这会做你想要的。

您可能会注意到我已经删除了变量周围的子表达式运算符($(...))。虽然他们有自己的位置,但不需要在这里使用。它们仅在更复杂的字符串中需要,例如当您需要扩展对象属性或其他内容时。