PowerShell:Set-Content与“文件已被使用”有关的问题 [英] PowerShell: Set-Content having issues with "file already in use"

查看:426
本文介绍了PowerShell:Set-Content与“文件已被使用”有关的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个PowerShell脚本,在给定的DIRECTORY中查找所有带PATTERN的文件,用PATTERN突出显示文档的相关行,然后用提供的REPLACE字替换PATTERN,然后保存回档。所以它实际上编辑文件。

除了我不能改变文件,因为Windows抱怨已经打开的文件。我尝试了几种方法来解决这个问题,但是一直在讨论这个问题。也许有人可以帮忙:

$ $ $ $ $ $ $ $ $ $ $ $ b $ ] $ replace =
,[string] $ directory =。
,[switch] $ recurse = $ false
,[switch] $ caseSensitive = $ false)

if($ pattern -eq $ null - 或$ pattern -eq)
{
写入错误请提供搜索模式。 ;返回
}

if($ directory -eq $ null - 或$ directory -eq)
{
写入错误请提供一个目录。 ;返回
}

if($ replace -eq $ null - 或$ replace -eq)
{
写入错误请提供一个字符串以替换。 ;返回
}

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

函数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])}
写主机`n
写主机已处理:$($ file)
}

问题位于Get-ChildItem调用的最后一段代码中。当然,由于我试图解决问题然后停止,所以在这个块中的一些代码现在有点损坏,但要记住脚本部分的意图。我想获取内容,替换单词,然后将修改后的文本保存到我从中获得的文件。



任何帮助都将不胜感激。 / p>

解决方案

删除我以前的答案,用这个替换它:

  Get-ChildItem $ directory -recurse:$ recurse 
foreach {
$ file =($ directory + $ _。FileName)
$ b $ - 内容$文件)| Foreach-object {
$ _ -replace([Regex] :: Escape([$ pattern])),[$ replace])
} Set-Content $ file
}

注意:


  • 围绕 Get-Content 的圆括号确保文件一气呵成(因此关闭)。 >
  • 连接后续命令而不是内联。

  • 一些命令已被删除,以确保它是一个简单的测试。

I'm working on a PowerShell script that finds all the files with PATTERN within a given DIRECTORY, prints out the relevant lines of the document with the PATTERN highlighted, and then replaces the PATTERN with a provided REPLACE word, then saves the file back. So it actually edits the file.

Except I can't get it to alter the file, because Windows complains about the file already being open. I tried several methods to solve this, but keep running into the issue. Perhaps someone can help:

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)"
    }

The issue is located within the final block of code, right at the Get-ChildItem call. Of course, some of the code in that block is now a bit mangled due to me trying to fix the problem then stopping, but keep in mind the intent of that part of the script. I want to get the content, replace the words, then save the altered text back to the file I got it from.

Any help at all would be greatly appreciated.

解决方案

Removed my previous answer, replacing it with this:

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

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

Note:

  • The parentheses around Get-Content to ensure the file is slurped in one go (and therefore closed).
  • The piping to subsequent commands rather than inlining.
  • Some of your commands have been removed to ensure it's a simple test.

这篇关于PowerShell:Set-Content与“文件已被使用”有关的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆