Gerenciamento de Arquivos de Texto: Como Ler e Editar com o PowerShell

Precisa 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 é para você. Ao final do post, vou mostrar uma função que criei para facilitar muito a sua vida.

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

  1. Lendo o arquivo
  2. Encontrando e substituindo a string
  3. Escrevendo as mudanças no arquivo.

Lendo o Arquivo

Primeiro, você precisa ler o arquivo. Vamos criar um com o cmdlet Set-Content para ter um com o qual 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 o caminho do arquivo de texto para o 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 na memória em uma string, precisamos buscar e substituir a string. Uma maneira de fazer isso é usando 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 busca foo com a string de substituição bar, o que deve fazer o conteúdo do arquivo ficar 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 escrever esse novo conteúdo de volta no arquivo. Uma maneira de fazer isso é usando 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 agora o arquivo C:\file.txt com Get-Content, verá que agora contém o novo conteúdo.

Lidando com Identificadores de Arquivos Abertos

As etapas pelas quais você passou anteriormente funcionam… na maioria das vezes. No entanto, na vida real, nem sempre acontece assim.

Você perceberá que ocasionalmente precisará lidar com arquivos que estão abertos pelo próprio PowerShell. Isso impede que você escreva os novos conteúdos de volta no 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 usa 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 expressões regulares permitirão uma busca 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 só vez. Isso é útil se você tiver um monte de arquivos para processar.

function Find-InTextFile {
    <#
    .SYNOPSIS
        Realiza uma busca (ou substituição) em uma string em um arquivo de texto ou arquivos.
    .EXAMPLE
        PS> Encontrar-EmArquivoTexto -CaminhoArquivo 'C:\MeuArquivo.txt' -Buscar 'água' -Substituir 'vinho'
    
        Substitui todas as ocorrências da string 'água' pela string 'vinho' em
        'C:\MeuArquivo.txt'.
    .EXAMPLE
        PS> Encontrar-EmArquivoTexto -CaminhoArquivo 'C:\MeuArquivo.txt' -Buscar 'água'
    
        Localiza todas as ocorrências da string 'água' no arquivo 'C:\MeuArquivo.txt'.
    .PARAMETER CaminhoArquivo
        O caminho do arquivo de texto em que você deseja realizar a busca/substituição.
    .PARAMETER Buscar
        A string que você deseja substituir.
    .PARAMETER Substituir
        A string pela qual você deseja substituir a string 'Buscar'.
    .PARAMETER NovoCaminhoArquivo
        Se um novo arquivo com a string substituída precisa ser criado em vez de substituir
        o conteúdo do arquivo existente, use esse parâmetro para criar um novo arquivo.
    .PARAMETER Forçar
        Se o parâmetro NovoCaminhoArquivo for usado, o uso desse parâmetro sobrescreverá qualquer arquivo
        que exista em NovoCaminhoArquivo.
    #>
    [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 obter mais informações sobre o comando Set-Content, confira Set-Content: A Forma do PowerShell de Escrever em um Arquivo ou uma maneira alternativa de escrever conteúdo em um arquivo, o comando Out-File.

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