¿Cómo puedo reemplazar cada aparición de una cadena en un archivo con PowerShell?

Resuelto amateur asked hace 11 años • 15 respuestas

Usando PowerShell, quiero reemplazar todas las apariciones exactas de [MYID]en un archivo determinado con MyValue. ¿Cuál es la forma más sencilla de hacerlo?

amateur avatar Jun 17 '13 16:06 amateur
Aceptado

Uso (versión V3):

(Get-Content c:\temp\test.txt).Replace('[MYID]', 'MyValue') | Set-Content c:\temp\test.txt

O para V2:

(Get-Content c:\temp\test.txt) -replace '\[MYID\]', 'MyValue' | Set-Content c:\temp\test.txt
Loïc MICHEL avatar Jun 17 '2013 09:06 Loïc MICHEL

Prefiero usar la clase File de .NET y sus métodos estáticos como se ve en el siguiente ejemplo.

$content = [System.IO.File]::ReadAllText("c:\bla.txt").Replace("[MYID]","MyValue")
[System.IO.File]::WriteAllText("c:\bla.txt", $content)

Esto tiene la ventaja de trabajar con una sola cadena en lugar de una matriz de cadenas como con Get-Content . Los métodos también se encargan de la codificación del archivo (UTF-8 BOM , etc.) sin que usted tenga que preocuparse la mayor parte del tiempo.

Además, los métodos no estropean los finales de línea (finales de línea de Unix que podrían usarse) en contraste con un algoritmo que usa Get-Content y pasa a Set-Content .

Entonces, para mí: menos cosas que puedan romperse con el paso de los años.

Una cosa poco conocida cuando se usan clases .NET es que cuando escribe "[System.IO.File]::" en la ventana de PowerShell, puede presionar la Tabtecla para recorrer los métodos allí.

rominator007 avatar Jun 17 '2015 14:06 rominator007
(Get-Content file.txt) | 
Foreach-Object {$_ -replace '\[MYID\]','MyValue'}  | 
Out-File file.txt

(Get-Content file.txt)Tenga en cuenta que se requiere el paréntesis :

Sin el paréntesis, el contenido se lee, una línea a la vez, y fluye hacia abajo en la tubería hasta que llega a out-file o set-content, que intenta escribir en el mismo archivo, pero ya está abierto por get-content y obtienes un error. El paréntesis hace que la operación de lectura del contenido se realice una vez (abrir, leer y cerrar). Solo entonces, cuando se hayan leído todas las líneas, se canalizarán una a la vez y cuando lleguen al último comando de la canalización se podrán escribir en el archivo. Es lo mismo que $content=content; $contenido | dónde ...

Shay Levy avatar Jun 17 '2013 10:06 Shay Levy

El de arriba solo se ejecuta para "Un archivo", pero también puede ejecutarlo para varios archivos dentro de su carpeta:

Get-ChildItem 'C:yourfile*.xml' -Recurse | ForEach {
     (Get-Content $_ | ForEach  { $_ -replace '[MYID]', 'MyValue' }) |
     Set-Content $_
}
John V Hobbs Jr avatar Jul 20 '2016 20:07 John V Hobbs Jr