2017-08-17 37 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表達式用於選擇要更改其值的屬性,以及該值的替換操作。 –

相關問題