53 votos

Cómo reemplazar varias cadenas en un archivo mediante powershell

Estoy escribiendo un guión para personalizar un archivo de configuración. Quiero reemplazar varias instancias de cadenas dentro de este archivo, y he intentado usar powershell para hacer el trabajo. Funciona muy bien para una sola reemplazar, pero haciendo varias reemplaza es muy lento porque cada vez que se tiene que analizar todo el archivo de nuevo, y este archivo es muy grande. La secuencia de comandos se parece a esto:

$original_file = 'path\filename.abc'
$destination_file =  'path\filename.abc.new'
(Get-Content $original_file) | Foreach-Object {
    $_ -replace 'something1', 'something1new'
    } | Set-Content $destination_file

Lo que quiero es algo como esto, pero no sé cómo escribir esto:

$original_file = 'path\filename.abc'
$destination_file =  'path\filename.abc.new'
(Get-Content $original_file) | Foreach-Object {
    $_ -replace 'something1', 'something1aa'
    $_ -replace 'something2', 'something2bb'
    $_ -replace 'something3', 'something3cc'
    $_ -replace 'something4', 'something4dd'
    $_ -replace 'something5', 'something5dsf'
    $_ -replace 'something6', 'something6dfsfds'
    } | Set-Content $destination_file

86voto

dahlbyk Puntos 24897

Una opción es la cadena de la-sustituir operaciones de forma conjunta. El ` al final de cada línea, escapa de la nueva línea, causando PowerShell para continuar con el análisis de la expresión en la línea siguiente:

$original_file = 'path\filename.abc'
$destination_file =  'path\filename.abc.new'
(Get-Content $original_file) | Foreach-Object {
    $_ -replace 'something1', 'something1aa' `
       -replace 'something2', 'something2bb' `
       -replace 'something3', 'something3cc' `
       -replace 'something4', 'something4dd' `
       -replace 'something5', 'something5dsf' `
       -replace 'something6', 'something6dfsfds'
    } | Set-Content $destination_file

Otra opción sería la de asignar una variable intermedia:

$x = $_ -replace 'something1', 'something1aa'
$x = $x -replace 'something2', 'something2bb'
...
$x

12voto

TroyB30 Puntos 186

para obtener el post by George Howarth trabajando correctamente con más de un repuesto que necesita para quitar la pausa, asignar el resultado a una variable ($) y luego la línea de salida de la variable.

$lookupTable = @{
'something1' = 'something1aa' 
'something2' = 'something2bb' 
'something3' = 'something3cc' 
'something4' = 'something4dd' 
'something5' = 'something5dsf' 
'something6' = 'something6dfsfds'
}

$original_file = 'path\filename.abc'
$destination_file =  'path\filename.abc.new'

Get-Content -Path $original_file | ForEach-Object { 
    $line = $_

    $lookupTable.GetEnumerator() | ForEach-Object {
        if ($line -match $_.Key)
        {
            $line = $line -replace $_.Key, $_.Value
        }
    }
   $line
} | Set-Content -Path $destination_file

4voto

George Howarth Puntos 1364

Suponiendo que usted sólo puede tener un 'something1' o 'something2' etc por línea, puede utilizar una tabla de búsqueda:

$lookupTable = @{
    'something1' = 'something1aa' 
    'something2' = 'something2bb' 
    'something3' = 'something3cc' 
    'something4' = 'something4dd' 
    'something5' = 'something5dsf' 
    'something6' = 'something6dfsfds'
}

$original_file = 'path\filename.abc'
$destination_file =  'path\filename.abc.new'

Get-Content -Path $original_file | ForEach-Object { 
    $line = $_

    $lookupTable.GetEnumerator() | ForEach-Object {
        if ($line -match $_.Key)
        {
            $line -replace $_.Key, $_.Value
            break
        }
    }
} | Set-Content -Path $destination_file

Si usted puede tener más de uno de esos, sólo hay que quitar la break en la if declaración.

2voto

Haakon Dahl Puntos 1

Una tercera opción, para un canalizadas one-liner es el nido-reemplaza:

PS> ("ABC" -replace "B","C") -replace "C","D"
ADD

Y:

PS> ("ABC" -replace "C","D") -replace "B","C"
ACD

Esto conserva el orden de ejecución, es fácil de leer, y encaja perfectamente en una tubería. Yo prefiero usar paréntesis para el control explícito, la auto-documentación, etc. Funciona sin ellos, pero ¿hasta qué confiar?

-Reemplazar es un Operador de Comparación, que acepta un objeto y devuelve un presumiblemente objeto modificado. Esta es la razón por la que se pueden apilar o nido, como se muestra arriba.

Por favor, consulte:

help about_operators

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: