web-dev-qa-db-fra.com

PowerShell Out-File: Empêchez les modifications de codage

Je travaille actuellement sur certaines recherches et remplacez l'opération que j'essaie d'automatiser l'utilisation de PowerShell. Malheureusement, j'ai reconnu hier que nous avons différents codages de fichiers dans notre codeBase (UTF8 et ASCII). Parce que nous effectuons ces recherches et remplacons les opérations dans une autre branche, je ne peux pas modifier les codages de fichiers à ce stade.

Si j'exécute les lignes suivantes, il modifie tous les fichiers sur UCS-2 Little Eindian, même si mon codage de PowerShell par défaut est défini sur ISO-8859-1 (Europe occidentale (Windows)).

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

Existe-t-il un moyen d'empêcher PowerShell de changer le codage du fichier?

25
Pete

Out-File a un codage par défaut sauf si de la nervure avec le -Encoding Paramètre:

Ce que j'ai fait pour résoudre ce problème, c'est essayer d'obtenir le codage du fichier d'origine en lisant d'essayer de le lire --- point d'ordre d'octet et en l'utilisant comme le-Encoding valeur de paramètre.

Voici un exemple de traitement de chemins de fichiers texte, d'obtenir l'encodage d'origine, de traiter le contenu et de la rédacter au fichier avec le codage de l'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
}

Mise à jour Voici un exemple d'obtention du codage du fichier d'origine à l'aide de la classe StreamReader. L'exemple lit les 3 premiers octets du fichier de sorte que la propriété CurrentEncoding est définie en fonction du résultat de sa routine de détection interne.

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

Le paramètre DétececCodingFromByeordermarks détecte le codage en examinant les trois premiers octets du flux. Il reconnaît automatiquement UTF-8, Little-Endian Unicode et Big-Endian Unicode Text si le fichier commence par les marques d'ordre d'octets appropriés. Sinon, l'UTF8ENCODING est utilisé. Voir la méthode encoding.getPreamble pour plus d'informations.

http://msdn.microsoft.com/en-us/library/system.text.encoding.getpeamble.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
39
Andy Arismendi