文本文件管理:如何使用PowerShell读取和编辑

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

不用再找了!这篇博文就是为你准备的。在本文末尾,我将向你展示一个我创建的函数,让你的生活变得更加轻松。

使用 PowerShell 替换文件中的文本是一个包含三个步骤的过程。

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

读取文件

首先,你需要读取文件。让我们首先使用 Set-Content cmdlet 创建一个文件,这样我们就有一个可以操作的文件了。

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 {
    <#
    .概要
        在文本文件或文件中查找(或替换)字符串。
    .示例
        PS> Find-InTextFile -FilePath 'C:\MyFile.txt' -Find 'water' -Replace 'wine'
    
        将字符串'water'的所有实例替换为字符串'wine'在
        'C:\MyFile.txt'中。
    .示例
        PS> Find-InTextFile -FilePath 'C:\MyFile.txt' -Find 'water'
    
        在文件'C:\MyFile.txt'中查找字符串'water'的所有实例。
    .参数 FilePath
        您想要执行查找/替换的文本文件的文件路径。
    .参数 Find
        您想要替换的字符串。
    .参数 Replace
        您想要用于替换'Find'字符串的字符串。
    .参数 NewFilePath
        如果需要创建一个替换了字符串的新文件,而不是替换
        使用此参数创建新文件的现有文件的内容。
    .参数 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/