Gestão de Arquivos de Texto: Como Ler e Editar com PowerShell

Precisa de saber como usar o PowerShell para ler um arquivo de texto e substituir texto? Isso é o que chamamos de PowerShell Read-Text File.

Não procure mais! Este post no blog é para você. No final do post, vou mostrar uma função que criei para facilitar muito a sua vida.

Substituir texto em um arquivo com PowerShell é um processo de três etapas.

  1. Lendo o arquivo
  2. Encontrando e substituindo a string
  3. Escrevendo alterações no arquivo.

Lendo o Arquivo

Primeiro, você precisará ler o arquivo. Vamos primeiro criar um com o cmdlet Set-Content para termos um com que trabalhar.

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

Para ler este arquivo, você pode usar o comando Get-Content. Você pode ler o arquivo fornecendo um caminho de arquivo de texto ao parâmetro Path conforme mostrado abaixo.

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

Encontrando e Substituindo a String

Agora que temos o conteúdo do arquivo em memória em uma string, precisamos procurar e substituir a string. Uma maneira de fazer isso é usar o operador -replace. Este operador PowerShell encontra uma string e a substitui por outra.

Usando o conteúdo do arquivo de exemplo, podemos fornecer a string de pesquisa foo com a string de substituição bar que deve tornar o conteúdo do arquivo foo foo baz agora.

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

Escrevendo no Arquivo

Agora que temos o novo conteúdo do arquivo salvo em $newContent, podemos agora escrever este novo conteúdo de volta para o arquivo. Uma maneira de fazer isso é usar o comando Set-Content.

O comando Set-Content substitui todo o conteúdo de um arquivo atribuindo um novo valor.

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

Quando você ler o arquivo C:\file.txt agora com Get-Content, verá que ele agora contém o novo conteúdo.

Lidando com Identificadores de Arquivo Abertos

As etapas que você passou anteriormente funcionam… na maioria das vezes. No entanto, você descobrirá no mundo real que nem sempre é assim.

Você verá que ocasionalmente terá que lidar com arquivos que estão abertos no próprio PowerShell. Isso impede que você escreva os novos conteúdos de volta para o arquivo.

Para remediar essa situação de identificador de arquivo aberto, criei um fluxo de trabalho simples que permite criar primeiro um arquivo de texto temporário no disco com os novos conteúdos, remover o arquivo original e, em seguida, renomear o arquivo temporário.

Aqui está um exemplo de como funciona:

$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

Abaixo está um exemplo de uma função que criei chamada Find-InTextFile que utiliza essa abordagem combinada com a capacidade de encontrar (não substituir) texto em um arquivo.

Esta função também utiliza a sintaxe mais poderosa de expressão regular para encontrar strings. Você verá que as expressões regulares permitirão uma pesquisa mais flexível usando caracteres especiais como aspas simples, caracteres especiais e muito mais.

Você também pode ver abaixo que estou usando um loop foreach para processar vários arquivos de uma vez. Isso é útil se você tiver um monte de arquivos para processar.

function Find-InTextFile {
    <#
    .SINOPSE
        Realiza uma busca (ou substituição) em uma string em um arquivo de texto ou arquivos.
    .EXEMPLO
        PS> Find-InTextFile -FilePath 'C:\MeuArquivo.txt' -Find 'água' -Replace 'vinho'
    
        Substitui todas as instâncias da string 'água' pela string 'vinho' em
        'C:\MeuArquivo.txt'.
    .EXEMPLO
        PS> Find-InTextFile -FilePath 'C:\MeuArquivo.txt' -Find 'água'
    
        Encontra todas as instâncias da string 'água' no arquivo 'C:\MeuArquivo.txt'.
    .PARÂMETRO FilePath
        O caminho do arquivo de texto no qual você gostaria de fazer uma busca/substituição.
    .PARÂMETRO Find
        A string que você gostaria de substituir.
    .PARÂMETRO Replace
        A string pela qual você gostaria de substituir sua string 'Find'.
    .PARÂMETRO NewFilePath
        Se um novo arquivo com a string substituída precisa ser criado em vez de substituir
        o conteúdo do arquivo existente, use este parâmetro para criar um novo arquivo.
    .PARÂMETRO Force
        Se o parâmetro NewFilePath for usado, o uso deste parâmetro irá sobrescrever qualquer arquivo que
        exista em 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
        }
    }
}

Recursos

Para mais informações sobre o comando Set-Content, consulte Set-Content: A Forma PowerShell de Escrever em um Arquivo ou uma forma alternativa de escrever conteúdo em um arquivo, o comando Out-File.

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