2014-02-26 25 views
0

我正在替換文件中的多個字符串。以下的作品,但它是做到這一點的最佳方式?我不確定是否執行多個塊表達式是一種好方法。powershell多塊表達式

(Get-Content $tmpFile1) | 
ForEach-Object {$_ -replace 'replaceMe1.*', 'replacedString1'} | 
      % {$_ -replace 'replaceMe2.*', 'replacedString2'} | 
      % {$_ -replace 'replaceMe3.*', 'replacedString3'} | 
Out-File $tmpFile2 

回答

2

您並不需要通過每個替換操作進行foreach。這些運營商可以在一個命令被鏈接:

@(Get-Content $tmpFile1) -replace 'replaceMe1.*', 'replacedString1' -replace 'replaceMe2.*', 'replacedString2' -replace 'replaceMe3.*', 'replacedString3' | 
Out-File $tmpFile2 
0

-replace operator使用正則表達式,所以你可以合併你的三個腳本塊到一個這樣的:

Get-Content $tmpFile1 ` 
    | ForEach-Object { $_ -replace 'replaceMe([1-3]).*', 'replacedString$1' } ` 
    | Out-File $tmpFile2 

這將爲文字文本搜索'replaceMe',然後是'1','2''3',並用'replacedString'替換它,然後找到其中的任何一個數字('$1')。

另外,請注意,-replace的作品類似於-match,而不是-like;也就是說,它使用正則表達式,而不是通配符。當您使用'replaceMe1.*'時,它不代表「文本'replaceMe1.'後跟零個或多個字符」,而是指「文本'replaceMe1'後跟零個或多個出現次數('*')的任意字符('.')」。下面演示將被替換,即使它不匹配通配符的文字:

PS> 'replaceMe1_some_extra_text_with_no_period' -replace 'replaceMe1.*', 'replacedString1' 
replacedString1 

通配符模式'replaceMe1.*'將在正則表達式可以寫爲'replaceMe1\..*',你會看到產生預期的結果(沒有替換執行):

PS> 'replaceMe1_some_extra_text_with_no_period' -replace 'replaceMe1\..*', 'replacedString1' 
replaceMe1_some_extra_text_with_no_period 

你可以閱讀更多關於在.NET Framework here正則表達式。

1

我打算假設你的模式和替換不是真的只是在結尾有一個不同的數字,所以你可能想要根據實際匹配的正則表達式來執行不同的代碼。 如果是這樣,您可以考慮使用單個正則表達式,但使用函數而不是替換字符串。唯一的問題是你必須使用正則表達式Replace而不是操作符。

PS C:\temp> set-content -value @" 
replaceMe1 something 
replaceMe2 something else 
replaceMe3 and another 
"@ -path t.txt 

PS C:\temp> Get-Content t.txt | 
ForEach-Object { ([regex]'replaceMe([1-3])(.*)').Replace($_, 
    { Param($m) 
    $head = switch($m.Groups[1]) { 1 {"First"}; 2 {"Second"}; 3 {"Third"} } 
    $tail = $m.Groups[2] 
    "Head: $head, Tail: $tail" 
    })} 
Head: First, Tail: something 
Head: Second, Tail: something else 
Head: Third, Tail: and another 

這可能是你今天需要什麼過於複雜,但它是值得記住你必須使用一個功能選項。