文本文件管理:使用PowerShell讀取和編輯的方法

需要知道如何使用PowerShell读取文本文件并替换文本?这就是我们所谓的PowerShell读取文本文件。

不用再找了!这篇博文就是为您准备的。在本文的最后,我将向您展示一个我编写的函数,可以让您的生活变得更轻松。

用PowerShell替换文件中的文本可以分为三个步骤。

  1. 读取文件
  2. 查找并替换字符串
  3. 将更改写入文件。

读取文件

首先需要读取文件。让我们首先使用Set-Content命令来创建一个文件,以便我们有一个可以使用的文件。

Set-Content -Path 'C:\file.txt' -Value 'foo bar baz'

要读取此文件,您可以使用Get-Content命令。您可以通过将文本文件路径提供给Path参数来读取文件,如下所示。

$content = Get-Content -Path 'C:\file.txt'

查找并替换字符串

现在,我们将文件内容以字符串的形式保存在内存中,我们需要搜索并替换字符串。一种方法是使用-replace运算符。这个PowerShell运算符可以找到一个字符串并将其替换为另一个字符串。

使用示例文件内容,我们可以将搜索字符串foo与替换字符串bar一起使用,这将使文件内容变为foo foo baz

PS> $newContent = $content -replace 'foo', 'bar'
bar bar baz

写入文件

現在我們已經將新檔案內容保存在$newContent中,我們現在需要將這個新內容寫回檔案。一種方法是使用Set-Content命令。

Set-Content命令將一個檔案的所有內容替換為新的值。

$newContent | Set-Content -Path 'C:\file.txt'

當你使用Get-Content讀取C:\file.txt檔案時,你會看到它現在包含了新的內容。

處理打開的檔案處理程序

你之前所做的步驟在大多數情況下都有效。然而,在現實世界中,情況並不總是如此。

你會發現,你偶爾需要處理那些已經被 PowerShell 打開的檔案。這會阻止你將新的內容寫回檔案。

為了解決這種打開的檔案處理程序問題,我創建了一個簡單的工作流程,允許你先在磁碟上創建一個臨時的文字檔,然後刪除原始檔案,最後重新命名臨時檔案。

以下是它的工作原理的示例:

$filePath = 'C:\file.txt'
$tempFilePath = "$env:TEMP\$($filePath | Split-Path -Leaf)"
$find = 'foo'
$replace = 'bar'

(Get-Content -Path $filePath) -replace $find, $replace | Add-Content -Path $tempFilePath

Remove-Item -Path $filePath
Move-Item -Path $tempFilePath -Destination $filePath

下面是我建立的一個名為Find-InTextFile的函數的示例,它使用了這種方法,結合了在檔案中查找(而不是替換)文字的能力。

此函數還使用了更強大的正則表達式語法來查找字符串。你會發現,正則表達式將允許你使用特殊字符如單引號、特殊字符等進行更靈活的搜索。

您還可以看到,我使用了一個foreach循環來同時處理多個文件。如果您有一堆文件需要處理,這很方便。

function Find-InTextFile {
    <#
    .SYNOPSIS
        在文本文件或文件中查找(或替換)字符串。
    .EXAMPLE
        PS> Find-InTextFile -FilePath 'C:\MyFile.txt' -Find 'water' -Replace 'wine'
    
        將字符串'water'在'C:\MyFile.txt'中的所有出現替換為字符串'wine'。
    .EXAMPLE
        PS> Find-InTextFile -FilePath 'C:\MyFile.txt' -Find 'water'
    
        在文件'C:\MyFile.txt'中查找字符串'water'的所有出現。
    .PARAMETER FilePath
        您要對其執行查找/替換的文本文件的文件路徑。
    .PARAMETER Find
        您要替換的字符串。
    .PARAMETER Replace
        您要用於替換'Find'字符串的字符串。
    .PARAMETER NewFilePath
        如果需要創建一個包含替換字符串的新文件,而不是替換現有文件的內容,請使用此參數創建一個新文件。
    .PARAMETER Force
        如果使用NewFilePath參數,使用此參數將覆蓋NewFilePath中存在的任何文件。
    #>
    [CmdletBinding(DefaultParameterSetName = 'NewFile')]
    [OutputType()]
    param (
        [Parameter(Mandatory = $true)]
        [ValidateScript({Test-Path -Path $_ -PathType 'Leaf'})]
        [string[]]$FilePath,
        [Parameter(Mandatory = $true)]
        [string]$Find,
        [Parameter()]
        [string]$Replace,
        [Parameter(ParameterSetName = 'NewFile')]
        [ValidateScript({ Test-Path -Path ($_ | Split-Path -Parent) -PathType 'Container' })]
        [string]$NewFilePath,
        [Parameter(ParameterSetName = 'NewFile')]
        [switch]$Force
    )
    begin {
        $Find = [regex]::Escape($Find)
    }
    process {
        try {
            foreach ($File in $FilePath) {
                if ($Replace) {
                    if ($NewFilePath) {
                        if ((Test-Path -Path $NewFilePath -PathType 'Leaf') -and $Force.IsPresent) {
                            Remove-Item -Path $NewFilePath -Force
                            (Get-Content $File) -replace $Find, $Replace | Add-Content -Path $NewFilePath -Force
                        } elseif ((Test-Path -Path $NewFilePath -PathType 'Leaf') -and !$Force.IsPresent) {
                            Write-Warning "The file at '$NewFilePath' already exists and the -Force param was not used"
                        } else {
                            (Get-Content $File) -replace $Find, $Replace | Add-Content -Path $NewFilePath -Force
                        }
                    } else {
                        (Get-Content $File) -replace $Find, $Replace | Add-Content -Path "$File.tmp" -Force
                        Remove-Item -Path $File
                        Move-Item -Path "$File.tmp" -Destination $File
                    }
                } else {
                    Select-String -Path $File -Pattern $Find
                }
            }
        } catch {
            Write-Error $_.Exception.Message
        }
    }
}

資源

有關 Set-Content 命令的更多信息,請查看 Set-Content:使用 PowerShell 寫入文件的方法 或者另一種將內容寫入文件的方法,即 Out-File 命令

Source:
https://adamtheautomator.com/powershell-read-text-file/