我有一个脚本,我需要替换几行。第一个替换正常,但第二个是擦除我的文件并多次重复该行。
我的代码
(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 等...
这是因为||?如果是这样,我该如何解决它?
谢谢!
答案 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
也许这会做你想要的。
您可能会注意到我已经删除了变量周围的子表达式运算符($(...)
)。虽然他们有自己的位置,但不需要在这里使用。它们仅在更复杂的字符串中需要,例如当您需要扩展对象属性或其他内容时。