PowerShell fuera de archivo: evitar cambios de codificación

Actualmente estoy trabajando en algunos operación de búsqueda y reemplazo que estoy tratando de automatizar el uso de powershell. Por desgracia me reconoció ayer que hemos de archivo diferentes codificaciones en nuestra base de código (UTF8 y ASCII). Porque estamos haciendo estos de búsqueda y reemplazo de las operaciones en una rama diferente yo no puedo cambiar el archivo de codificaciones en esta etapa.

Si estoy ejecutando las siguientes líneas cambia todos los archivos a UCS-2 Poco Eindian a pesar de que mi defecto powershell codificación se establece en la norma iso-8859-1 (Europeo Occidental (Windows)).

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

Es allí una manera de prevenir el powershell de cambiar la codificación del archivo?

InformationsquelleAutor Pete | 2012-02-02

1 Kommentar

  1. 36

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

    Lo que he hecho para resolver este problema es tratar de conseguir el archivo original de la codificación de la lectura tratando de leer es marca de orden de bytes y su uso como el-Encoding valor del parámetro.

    He aquí un ejemplo de procesamiento de una gran cantidad de texto rutas de acceso de archivo, obtener el original de la codificación, el procesamiento de los contenidos y de escribir de nuevo en el archivo con el original de la codificación.

    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
    }

    Actualización Aquí es un ejemplo de obtención de la codificación del archivo original utilizando la clase StreamReader. El ejemplo lee los 3 primeros bytes del archivo de modo que el CurrentEncoding propiedad se basa en el resultado de su interior BOM de detección de rutina.

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

    La detectEncodingFromByteOrderMarks parámetro detecta la codificación por
    mirando a los tres primeros bytes de la secuencia. Automáticamente
    reconoce UTF-8, «little-endian» Unicode, y big-endian de texto Unicode
    si el archivo se inicia con la correspondiente marca de orden de byte. De lo contrario,
    el UTF8Encoding se utiliza. Ver la Codificación.GetPreamble método 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
    • Ya he pensado en ello, pero debe haber una manera más fácil, ¿no? Pero que a mí me funciona ahora. Gracias Andy!
    • Vas a tener que conseguir la codificación. No hay un cmdlet de que va a obtener de usted. He actualizado mi respuesta la adición de un enfoque diferente. Ambas formas de uso de la lista de materiales de detección.
    • Set-Content -Path BOM_Utf32.txt -Value $null -Encoding UTF32 escribe UTF-32, «little-endian» BOM es decir, FF FE 00 00 secuencia de bytes. Sin embargo, la función de Get-FileEncoding devuelve Unicode. Por otro lado, 00 00 FE FF secuencia de bytes es reconocido como UTF32 pero como por El Consorcio Unicode este es el UTF-32, big-endian lista de materiales. Estoy equivocado? ¿Dónde está el error?

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea