Administración de archivos de texto: Cómo leer y editar con PowerShell

¿Necesitas saber cómo usar PowerShell para leer un archivo de texto y reemplazar texto? Esto es lo que llamamos PowerShell Leer-Archivo de Texto.

¡No busques más! Este artículo del blog es para ti. Al final del post, te mostraré una función que construí para hacer tu vida mucho más fácil.

Reemplazar texto en un archivo con PowerShell es un proceso de tres pasos.

  1. Lectura del archivo
  2. Buscar y reemplazar la cadena
  3. Guardar cambios en el archivo.

Lectura del Archivo

Primero necesitarás leer el archivo. Vamos a crear uno con el cmdlet Set-Content para tener uno con el que trabajar.

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

Para leer este archivo, puedes usar el comando Get-Content. Puedes leer el archivo proporcionando una ruta de archivo de texto al parámetro Path como se muestra a continuación.

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

Buscar y Reemplazar la Cadena

Ahora que tenemos el contenido del archivo en la memoria en una cadena, necesitamos buscar y reemplazar la cadena. Una forma de hacerlo es usar el operador -replace. Este operador de PowerShell encuentra una cadena y la reemplaza por otra.

Usando el contenido del archivo de ejemplo, podemos proporcionar la cadena de búsqueda foo con la cadena de reemplazo bar lo que debería hacer que el contenido del archivo sea foo foo baz ahora.

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

Escribir en el Archivo

Ahora que tenemos el nuevo contenido del archivo guardado en $newContent, podemos escribir este nuevo contenido de vuelta al archivo. Una forma de hacerlo es utilizando el comando Set-Content.

El comando Set-Content reemplaza todo el contenido de un archivo asignándole un nuevo valor.

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

Cuando ahora leas el archivo C:\file.txt con Get-Content, verás que ahora contiene el nuevo contenido.

Manejo de Manijas de Archivos Abiertos

Los pasos que has seguido anteriormente funcionan… la mayor parte del tiempo. Sin embargo, encontrarás en el mundo real que no siempre resulta así.

Te darás cuenta de que ocasionalmente tendrás que lidiar con archivos que están abiertos en PowerShell mismo. Esto te impide escribir los nuevos contenidos de vuelta al archivo.

Para remediar esta situación de manija de archivo abierta, creé un flujo de trabajo simple que te permite crear primero un archivo de texto temporal en disco con los nuevos contenidos, eliminar el archivo original y luego renombrar el archivo temporal.

Aquí tienes un ejemplo de cómo 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

A continuación se muestra un ejemplo de una función que creé llamada Find-InTextFile que utiliza este enfoque combinado con la capacidad de buscar (no reemplazar) texto en un archivo.

Esta función también utiliza la sintaxis más potente de expresiones regulares para encontrar cadenas. Descubrirás que las expresiones regulares te permitirán realizar búsquedas más flexibles utilizando caracteres especiales como comillas simples, caracteres especiales y más.

Puedes ver también a continuación que estoy usando un bucle foreach para procesar varios archivos a la vez. Esto es útil si tienes un montón de archivos para procesar.

function Find-InTextFile {
    <#
    .SINOPSIS
        Realiza una búsqueda (o reemplazo) en una cadena en un archivo de texto o archivos.
    .EJEMPLO
        PS> Find-InTextFile -FilePath 'C:\MiArchivo.txt' -Find 'agua' -Replace 'vino'
    
        Reemplaza todas las instancias de la cadena 'agua' por la cadena 'vino' en
        'C:\MiArchivo.txt'.
    .EJEMPLO
        PS> Find-InTextFile -FilePath 'C:\MiArchivo.txt' -Find 'agua'
    
        Encuentra todas las instancias de la cadena 'agua' en el archivo 'C:\MiArchivo.txt'.
    .PARÁMETRO FilePath
        La ruta del archivo de texto en el que desea realizar una búsqueda/reemplazo.
    .PARÁMETRO Find
        La cadena que desea reemplazar.
    .PARÁMETRO Replace
        La cadena por la que desea reemplazar su cadena 'Find'.
    .PARÁMETRO NewFilePath
        Si necesita crear un nuevo archivo con la cadena reemplazada en lugar de reemplazar
        el contenido del archivo existente, utilice este parámetro para crear un nuevo archivo.
    .PARÁMETRO Force
        Si se utiliza el parámetro NewFilePath, utilizando este parámetro se sobrescribirá cualquier archivo que
        exista en 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 obtener más información sobre el comando Set-Content, consulta Set-Content: La forma de PowerShell de escribir en un archivo o una forma alternativa de escribir contenidos en un archivo, el comando Out-File.

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