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?