powershell scripting replace find

Script de PowerShell para buscar y reemplazar todos los archivos con una extensión específica



powershell replace string in file (8)

Al hacer un reemplazo recursivo, la ruta y el nombre del archivo deben ser incluidos:

Get-ChildItem -Recurse | ForEach { (Get-Content $_.PSPath | ForEach {$ -creplace "old", "new"}) | Set-Content $_.PSPath }

Esto reemplazará todos los "viejos" por "nuevos" mayúsculas y minúsculas en todos los archivos de sus carpetas de su directorio actual.

Tengo varios archivos de configuración en Windows Server 2008 anidados así:

C:/Projects/Project_1/project1.config C:/Projects/Project_2/project2.config

En mi configuración necesito hacer una cadena de reemplazo como tal:

<add key="Environment" value="Dev"/>

se convertirá:

<add key="Environment" value="Demo"/>

Pensé en usar scripts por lotes, pero no había una buena manera de hacerlo, y escuché que con el scripting de PowerShell puedes realizar esto fácilmente. He encontrado ejemplos de find / replace, pero esperaba una forma de atravesar todas las carpetas dentro de mi directorio C: / Projects y encontrar cualquier archivo que termine con la extensión ''.config''. Cuando encuentre uno, quiero que reemplace mis valores de cadena.

¿Algún buen recurso para averiguar cómo hacer esto o cualquier gurú de PowerShell que pueda ofrecer alguna información?


Aquí un primer intento en la parte superior de mi cabeza.

$configFiles = Get-ChildItem . *.config -rec foreach ($file in $configFiles) { (Get-Content $file.PSPath) | Foreach-Object { $_ -replace "Dev", "Demo" } | Set-Content $file.PSPath }


Este ejemplo de PowerShell busca todas las instancias de la cadena "/ foo /" en una carpeta y sus subcarpetas, reemplaza "/ foo /" por "/ bar /" Y NO REESCRIBE archivos que no contengan la cadena "/ foo /" "De esta forma no se destruye el archivo de la última actualización de sellos de fecha y hora donde no se encontró la cadena:

Get-ChildItem -Path C:/YOUR_ROOT_PATH/*.* -recurse | ForEach {If (Get-Content $_.FullName | Select-String -Pattern ''//foo//') {(Get-Content $_ | ForEach {$_ -replace ''//foo//', ''/bar/'}) | Set-Content $_ } }


Este enfoque funciona bien:

gci C:/Projects *.config -recurse | ForEach { (Get-Content $_ | ForEach {$_ -replace "old", "new"}) | Set-Content $_ }

  • Cambia "viejo" y "nuevo" a sus valores correspondientes (o usa variables).
  • No olvide el paréntesis, sin el cual recibirá un error de acceso.

He escrito una pequeña función auxiliar para reemplazar texto en un archivo:

function Replace-TextInFile { Param( [string]$FilePath, [string]$Pattern, [string]$Replacement ) [System.IO.File]::WriteAllText( $FilePath, ([System.IO.File]::ReadAllText($FilePath) -replace $Pattern, $Replacement) ) }

Ejemplo:

Get-ChildItem . *.config -rec | ForEach-Object { Replace-TextInFile -FilePath $_ -Pattern ''old'' -Replacement ''new'' }


Me gustaría ir con xml y xpath:

dir C:/Projects/project_*/project*.config -recurse | foreach-object{ $wc = [xml](Get-Content $_.fullname) $wc.SelectNodes("//add[@key=''Environment''][@value=''Dev'']") | Foreach-Object {$_.value = ''Demo''} $wc.Save($_.fullname) }


PowerShell es una buena opción;) Es muy fácil enumerar archivos en un directorio determinado, leerlos y procesarlos.

El script podría verse así:

Get-ChildItem C:/Projects *.config -recurse | Foreach-Object { $c = ($_ | Get-Content) $c = $c -replace ''<add key="Environment" value="Dev"/>'',''<add key="Environment" value="Demo"/>'' [IO.File]::WriteAllText($_.FullName, ($c -join "`r`n")) }

Divido el código en más líneas para que pueda leerlo. Tenga en cuenta que puede usar Set-Content en lugar de [IO.File]::WriteAllText , pero agrega una nueva línea al final. Con WriteAllText puedes evitarlo.

De lo contrario, el código podría verse así: $c | Set-Content $_.FullName $c | Set-Content $_.FullName .


@Artyom útil el comentario de @Artyom pero lamentablemente no ha publicado una respuesta.

Esta es la versión corta, en mi opinión la mejor versión, de la respuesta aceptada;

ls *.config -rec | %{$f=$_; (gc $f.PSPath) | %{$_ -replace "Dev", "Demo"} | sc $f.PSPath}