2014-02-17 40 views
3

我不能得到這個工作,工作它不喜歡的「(」字符。?「(」字符不會在PowerShell中

如何解決呢

Dir | Rename-Item -NewName { $_.name -replace "(","" } 

我該如何處理這種類型的特殊字符在PowerShell中?

+2

我有'powershell'沒有經驗,因爲像大多數其他用戶在這裏我工作在Linux上,並使用標準shell像'bash'代替。但是在所有環境中都應該是一樣的:你必須「逃避」具有控制意義的特殊字符。因此,請注意如何在PowerShell中轉義字符,最有可能是'backslash':'Dir | Rename-Item -NewName {$ _。name -replace「\(」,「」}'。但是再一次:如果有些東西是典型的,MS總是以另一種方式做事,所以它可能是另一個需要使用的角色。檢查文檔 – arkascha

+4

@arkascha請調整不專業的反MS的態度,它並沒有真正幫助回答這個問題,因爲.Net確實使用'\'作爲正則表達式中的轉義字符 – vonPryz

+0

@vonPryz我沒有看到什麼問題是:這不是「態度」或任何東西,我給出了一個暗示,這是怎麼完成的(閱讀:在其他shell中),並添加了一個提示,這可能在MS環境中稍有不同(您確認)。它_does_幫助,因爲它指出了正確的道路 – arkascha

回答

9

你得從@vonPryze你的問題的確切原因的很好的解釋,但還有一個更簡單的解決方案。 -replace運算符使用需要轉義的正則表達式,但.Replace()字符串方法僅使用字符串。所以,如果你並不需要一個正則表達式,只是使用的方法,而且也沒有必要逃避什麼:

dir | rename-item -NewName { $_.name.Replace("(","") } 
+3

另外,我認爲應該提到,'Replace'方法區分大小寫,但速度更快比'-Replace'運算符。 –

4
Dir | Rename-Item -NewName { $_.name -replace "\(","" } # This works 
9

讓我們試着分析問題一點。首先,創建包含像這樣一個括號一些虛擬的文件,

for($i=0;$i -le 4; ++$i) { set-content -path $("file($i).txt" -f $i) -value $i } 
Output: 
gci 
    Directory: C:\temp\foo 
Mode    LastWriteTime  Length Name 
----    -------------  ------ ---- 
-a---   17.2.2014  10:34   3 file(0).txt 
-a---   17.2.2014  10:34   3 file(1).txt 
-a---   17.2.2014  10:34   3 file(2).txt 
-a---   17.2.2014  10:34   3 file(3).txt 
-a---   17.2.2014  10:34   3 file(4).txt 

現在,我們有一些測試數據,讓我們試着運行provied的錯誤消息,像這樣的命令,

Dir | Rename-Item -NewName { $_.name -replace "(","" } 

Rename-Item : The input to the script block for parameter 'NewName' failed. 
Invalid regular expression pattern: (. 
At line:1 char:27 
+ Dir | Rename-Item -NewName <<<< { $_.name -replace "(","" } 
    + CategoryInfo   : InvalidArgument: (file(0).txt:PSObject) [Rename-Item], ParameterBind ingException 
    + FullyQualifiedErrorId : ScriptBlockArgumentInvocationFailed,Microsoft.PowerShell.Commands.Re nameItemCommand 

糟糕!錯誤消息說使用了一個無效的正則表達式。這意味着-replace不會替換字符串,但它也支持regular expressions

爲了得到-replace將輸入視爲文字文本而不是正則表達式,輸入需要被轉義。簡單的方法是插入反斜槓\,但這很快就會變得乏味。幸運的是更簡單的方法,因爲.Net Regex類有一個內置的轉義方法[Regex]::Excape()。像這樣,

Dir | Rename-Item -NewName { $_.name -replace [regex]::escape("("),"" } 
Output: 
ls 
    Directory: C:\temp\foo 
Mode    LastWriteTime  Length Name 
----    -------------  ------ ---- 
-a---   17.2.2014  10:34   3 file0).txt 
-a---   17.2.2014  10:34   3 file1).txt 
-a---   17.2.2014  10:34   3 file2).txt 
-a---   17.2.2014  10:34   3 file3).txt 
-a---   17.2.2014  10:34   3 file4).txt