2017-08-17 39 views
1

我试图更新一组基于XML的.config文件。有一个包含一个加号,我不能用我的脚本替换文件中的字符串:无法通过PowerShell在文本文件中使用加号“+”替换字符串值

< SharedPassKey=123456789abcdefghi/JKLM+nopqrst= /> 

如果我包括加号,该脚本不执行任何操作。由于所有的配置不同,我需要替换文本 - 不能只用新文件。

想要的结果是文件中的匹配值被替换为指定的值,但+符号不允许这样做。这是我PS的脚本:

$DIRs = Get-ChildItem -Path "C:\TEST" -Directory 
Get-ChildItem $DIRs -File -Recurse -Filter *.config | 
    ForEach { (Get-Content $_.FullName) | 
    ForEach { $_ -replace '< SharedPassKey=123456789abcdefghi/JKLM+nopqrst= />','< SharedPassKey=123456789abcdefghi/JKLM.nopqrst= />' } | 
    Set-Content $_.FullName } 

作为一个测试,我全部换成了文字到加号,它工作得很好,但我已经离开出现在新文本的末尾加号以下是脚本中的“+ nopqrst”。

在PSv3上运行,FYI。

+1

尝试加号前的反斜杠字符 – thepi

+0

'< foo=bar= />'无效的XML。你的数据是真的吗?否则,使用XML解析器可能是更合适的方法。 –

+0

@AnsgarWiechers - 没有我的XML是正常的,这只是一个快速表示,所有的信息都被剥离了。 –

回答

6

-replace运算符使用第一个后​​缀参数的正则表达式来定义搜索模式。在正则表达式中,某些字符有special meaning。特别是具有“先前(子)表达的一倍或多倍”含义的所谓“量词”。为了替换文字特殊字符,您需要将其转义。

幸运的是,有一个内置的method for escaping strings

$_ -replace [RegEx]::Escape('< SharedPassKey=123456789abcdefghi/JKLM+nopqrst= />'),'< SharedPassKey=123456789abcdefghi/JKLM.nopqrst= />' 
+1

请注意,'[regex] :: Escape()'会转义给定字符串中的所有特殊字符。如果你只是想用另一个文字(子)字符串替换,你可能需要考虑使用'String.Replace()'方法:'$ _。Replace('foo','bar')'。 –

+0

两者都非常有帮助! @Ansgar,谢谢你的提示,我没有用过这种方法,但将来不会回避。 –

+0

@Bacon比特为我解决了这个问题!他对我的剧本的调整证明是成功的。谢谢! –

0

如果您有有效的XML数据,并且要修改XML文件中的节点属性的值,你可能要考虑使用适当的XML解析器,像这样:

$xmlfile = 'C:\path\to\your.config' 

[xml]$xml = Get-Content $xmlfile 
$attr = $xml.SelectSingleNode('//somenode/@SharedPassKey') 
$attr.'#text' = $attr.'#text'.Replace('+', '.') 

$xml.Save($xmlfile) 

充分利用XPath expression选择属性具体,因为它必须这样做。这将允许您仅使用该属性中的.替换+

+0

嗨安斯加,我一直这样做 - 替换了很长一段时间,但最后一个特殊的角色阻止了我在我的轨道。 我不熟悉你提供的方法,它似乎没有留下的例子会覆盖子目录中的多个文件。我也不知道如何指定要用此方法编辑的字符串。 显然,我不期待上课,我现在正在做我自己的研究/学习,但是,您的意见和以前的评论非常感谢。如果我可以学习这种方法,它可能被证明是更有效的。 –

+0

该代码仅是如何使用XML解析器替换属性值的示例。这并不意味着成为一个交钥匙解决方案。此外,使用这种方法,您不需要指定单个字符串。您有一个XPath表达式用于选择要更改其值的属性,以及该值的替换操作。 –

相关问题