usar tutorial script como commands comandos powershell

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



powershell tutorial (11)

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


Crédito a @ rominator007

Lo envolví en una función (porque es posible que desee utilizarla de nuevo)

function Replace-AllStringsInFile($SearchString,$ReplaceString,$FullPathToFile) { $content = [System.IO.File]::ReadAllText("$FullPathToFile").Replace("$SearchString","$ReplaceString") [System.IO.File]::WriteAllText("$FullPathToFile", $content) }

NOTA: Esto NO es sensible a mayúsculas y minúsculas!

Ver este post: String . Reemplazar caso ignorando


Después de buscar demasiado, descubro que la línea más simple para hacer esto sin cambiar la codificación es:

Get-Content path/to/file.ext | out-file -encoding ASCII targetFile.ext


El anterior solo se ejecuta para "Un archivo" solo, 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 $_ }


Esto es lo que uso, pero es lento en archivos de texto grandes.

get-content $pathToFile | % { $_ -replace $stringToReplace, $replaceWith } | set-content $pathToFile

Si va a reemplazar cadenas en archivos de texto grandes y la velocidad es una preocupación, considere el uso de System.IO.StreamReader y System.IO.StreamWriter .

try { $reader = [System.IO.StreamReader] $pathToFile $data = $reader.ReadToEnd() $reader.close() } finally { if ($reader -ne $null) { $reader.dispose() } } $data = $data -replace $stringToReplace, $replaceWith try { $writer = [System.IO.StreamWriter] $pathToFile $writer.write($data) $writer.close() } finally { if ($writer -ne $null) { $writer.dispose() } }

(El código de arriba no ha sido probado.)

Probablemente haya una forma más elegante de usar StreamReader y StreamWriter para reemplazar texto en un documento, pero eso debería darle un buen punto de partida.


Esto me funcionó utilizando el directorio de trabajo actual en PowerShell. FullName usar la propiedad FullName , o no funcionará en la versión 5 de PowerShell. Necesitaba cambiar la versión del marco .NET de destino en TODOS mis archivos CSPROJ .

gci -Recurse -Filter *.csproj | % { (get-content "$($_.FullName)") .Replace(''<TargetFramework>net47</TargetFramework>'', ''<TargetFramework>net462</TargetFramework>'') | Set-Content "$($_.FullName)"}


Pequeña corrección para el comando Set-Content. Si no se encuentra la cadena buscada, el comando Set-Content pondrá en blanco (vacío) el archivo de destino.

Primero puede verificar si la cadena que está buscando existe o no. Si no, no reemplazará nada.

If (select-string -path "c:/Windows/System32/drivers/etc/hosts" -pattern "String to look for") ` {(Get-Content c:/Windows/System32/drivers/etc/hosts).replace(''String to look for'', ''String to replace with'') | Set-Content c:/Windows/System32/drivers/etc/hosts} Else{"Nothing happened"}


Podrías probar algo como esto:

$path = "C:/testFile.txt" $word = "searchword" $replacement = "ReplacementText" $text = get-content $path $newText = $text -replace $word,$replacement $newText > $path


Prefiero usar la clase de archivo 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 cadena 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 cuidar la mayor parte del tiempo.

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

Así que para mí: Menos cosas que podrían romperse con 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 tecla Tab para avanzar a través de los métodos allí.


Un poco viejo y diferente, ya que necesitaba cambiar una determinada línea en todas las instancias de un nombre de archivo en particular.

Además, Set-Content no daba resultados consistentes, así que tuve que recurrir a Out-File .

Código abajo:

$FileName ='''' $OldLine = '''' $NewLine = '''' $Drives = Get-PSDrive -PSProvider FileSystem foreach ($Drive in $Drives) { Push-Location $Drive.Root Get-ChildItem -Filter "$FileName" -Recurse | ForEach { (Get-Content $_.FullName).Replace($OldLine, $NewLine) | Out-File $_.FullName } Pop-Location }

Esto es lo que mejor me funcionó en esta versión de PowerShell:

Major.Minor.Build.Revision

5.1.16299.98


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


(Get-Content file.txt) | Foreach-Object {$_ -replace ''/[MYID/]'',''MyValue''} | Out-File file.txt

Tenga en cuenta que se requieren los paréntesis alrededor de (Get-Content file.txt) :

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