2012-04-20 42 views
3

我正在研究一個PowerShell腳本,該腳本可以在指定的目錄中找到PATTERN中的所有文件,打印出帶有突出顯示的PATTERN的文檔的相關行,然後用提供的REPLACE字代替PATTERN,然後將文件保存回去。所以它實際上是編輯文件。PowerShell:Set-Content與「文件已在使用」有關的問題

除了我不能改變文件,因爲Windows抱怨已經打開的文件。我嘗試了幾種方法來解決這個問題,但是一直在解決這個問題。也許有人可以提供幫助:

param(
    [string] $pattern = "" 
    ,[string] $replace = "" 
    ,[string] $directory ="." 
    ,[switch] $recurse = $false 
    ,[switch] $caseSensitive = $false) 

if($pattern -eq $null -or $pattern -eq "") 
{ 
    Write-Error "Please provide a search pattern." ; return 
} 

if($directory -eq $null -or $directory -eq "") 
{ 
    Write-Error "Please provide a directory." ; return 
} 

if($replace -eq $null -or $replace -eq "") 
{ 
    Write-Error "Please provide a string to replace." ; return 
} 

$regexPattern = $pattern 
if($caseSensitive -eq $false) { $regexPattern = "(?i)$regexPattern" } 
$regex = New-Object System.Text.RegularExpressions.Regex $regexPattern 

function Write-HostAndHighlightPattern([string] $inputText) 
{ 
    $index = 0 
    $length = $inputText.Length 
    while($index -lt $length) 
    { 
     $match = $regex.Match($inputText, $index) 
     if($match.Success -and $match.Length -gt 0) 
     { 
      Write-Host $inputText.SubString($index, $match.Index) -nonewline 
      Write-Host $match.Value.ToString() -ForegroundColor Red -nonewline 
      $index = $match.Index + $match.Length 
     } 
     else 
     { 
      Write-Host $inputText.SubString($index) -nonewline 
      $index = $inputText.Length 
     } 
    } 
} 

Get-ChildItem $directory -recurse:$recurse | 
    Select-String -caseSensitive:$caseSensitive -pattern:$pattern |  
    foreach { 
     $file = ($directory + $_.FileName) 
     Write-Host "$($_.FileName)($($_.LineNumber)): " -nonewline 
     Write-HostAndHighlightPattern $_.Line 
     %{ Set-Content $file ((Get-Content $file) -replace ([Regex]::Escape("[$pattern]")),"[$replace]")} 
     Write-Host "`n" 
     Write-Host "Processed: $($file)" 
    } 

該問題位於Get-ChildItem調用的最後一段代碼內。當然,由於我試圖解決問題然後停止,所以該塊中的一些代碼現在有點損壞,但請記住該腳本部分的意圖。我想獲取內容,替換單詞,然後將修改後的文本保存回我從中獲得的文件。

任何幫助都將不勝感激。

回答

0

只是一個建議,但您可以嘗試查看參數代碼塊的文檔。有一種更有效的方法可以確保在需要時輸入參數並在用戶不知道的情況下拋出錯誤消息。

About_throw:http://technet.microsoft.com/en-us/library/dd819510.aspx About_functions_advanced_pa​​rameters:http://technet.microsoft.com/en-us/library/dd347600.aspx

然後有關使用寫主機的所有時間:http://powershell.com/cs/blogs/donjones/archive/2012/04/06/2012-scripting-games-commentary-stop-using-write-host.aspx

4

打消了我以前的答案,這個替換它:

Get-ChildItem $directory -recurse:$recurse 
foreach {   
    $file = ($directory + $_.FileName) 

    (Get-Content $file) | Foreach-object { 
     $_ -replace ([Regex]::Escape("[$pattern]")),"[$replace]") 
    } | Set-Content $file 
} 

注意:

  • 圍繞Get-Content的括號以確保文件一氣呵成(因此關閉)。
  • 將管道連接到後續命令而不是內聯。
  • 你的一些命令已被刪除,以確保它是一個簡單的測試。
+0

它一直給我一個與括號數有關的錯誤,但任何移動它們的數量都是徒勞的。但是,我喜歡這個更好,當然會做一些修改,一定會使用它。非常感謝。我還沒有完成腳本的工作,但我認爲通過所有這些修改,我就更接近了。 – 2012-04-20 23:27:47

+0

圍繞Get-Content的括號對我來說是關鍵 – 2015-04-29 22:02:02

0

好吧,我終於坐下來,只是在PowerShell中按順序輸入所有東西,然後用它來製作我的腳本。

這其實很簡單;

​​

感謝您的幫助。