powershell encoding file-encodings

PowerShell fuera de archivo: evitar cambios de codificación



encoding file-encodings (1)

Out-File tiene una codificación predeterminada a menos que se sobrescriba con el parámetro -Encoding :

Lo que he hecho para resolver esto es intentar obtener la codificación del archivo original leyendo tratando de leer su marca de orden de bytes y usándola como el valor del parámetro -Encoding .

Aquí hay un ejemplo que procesa un conjunto de rutas de archivos de texto, obtiene la codificación original, procesa el contenido y lo vuelve a escribir en un archivo con la codificación del original.

function Get-FileEncoding { param ( [string] $FilePath ) [byte[]] $byte = get-content -Encoding byte -ReadCount 4 -TotalCount 4 -Path $FilePath if ( $byte[0] -eq 0xef -and $byte[1] -eq 0xbb -and $byte[2] -eq 0xbf ) { $encoding = ''UTF8'' } elseif ($byte[0] -eq 0xfe -and $byte[1] -eq 0xff) { $encoding = ''BigEndianUnicode'' } elseif ($byte[0] -eq 0xff -and $byte[1] -eq 0xfe) { $encoding = ''Unicode'' } elseif ($byte[0] -eq 0 -and $byte[1] -eq 0 -and $byte[2] -eq 0xfe -and $byte[3] -eq 0xff) { $encoding = ''UTF32'' } elseif ($byte[0] -eq 0x2b -and $byte[1] -eq 0x2f -and $byte[2] -eq 0x76) { $encoding = ''UTF7''} else { $encoding = ''ASCII'' } return $encoding } foreach ($textFile in $textFiles) { $encoding = Get-FileEncoding $textFile $content = Get-Content -Encoding $encoding # Process content here... $content | Set-Content -Path $textFile -Encoding $encoding }

Actualizar Aquí hay un ejemplo de cómo obtener la codificación del archivo original usando la clase StreamReader. El ejemplo lee los primeros 3 bytes del archivo para que la propiedad CurrentEncoding se configure en función del resultado de su rutina de detección de BOM interna.

http://msdn.microsoft.com/en-us/library/9y86s1a9.aspx

El parámetro detectEncodingFromByteOrderMarks detecta la codificación mirando los primeros tres bytes de la secuencia. Reconoce automáticamente UTF-8, Unicode little-endian y texto Unicode big-endian si el archivo comienza con las marcas de orden de bytes apropiadas. De lo contrario, se utiliza el UTF8Encoding. Consulte el método Encoding.GetPreamble para obtener más información.

http://msdn.microsoft.com/en-us/library/system.text.encoding.getpreamble.aspx

$text = @" This is my text file contents. "@ #Create text file. [IO.File]::WriteAllText($filePath, $text, [System.Text.Encoding]::BigEndianUnicode) #Create a stream reader to get the file''s encoding and contents. $sr = New-Object System.IO.StreamReader($filePath, $true) [char[]] $buffer = new-object char[] 3 $sr.Read($buffer, 0, 3) $encoding = $sr.CurrentEncoding $sr.Close() #Show the detected encoding. $encoding #Update the file contents. $content = [IO.File]::ReadAllText($filePath, $encoding) $content2 = $content -replace "my" , "your" #Save the updated contents to file. [IO.File]::WriteAllText($filePath, $content2, $encoding) #Display the result. Get-Content $filePath

Actualmente estoy trabajando en algunas operaciones de búsqueda y reemplazo que estoy tratando de automatizar con PowerShell. Lamentablemente, reconocí ayer que tenemos diferentes codificaciones de archivos en nuestra base de código (UTF8 y ASCII). Debido a que estamos realizando estas operaciones de búsqueda y reemplazo en una rama diferente, no puedo cambiar las codificaciones de los archivos en esta etapa.

Si estoy ejecutando las siguientes líneas, cambiará todos los archivos a UCS-2 Little Eindian aunque mi codificación PowerShell predeterminada está configurada en iso-8859-1 (Europa occidental (Windows)).

$content = Get-Content $_.Path $content -replace ''myOldText'' , ''myNewText'' | Out-File $_.Path

¿Hay alguna manera de evitar que PowerShell cambie la codificación del archivo?