PowerShell out-file:阻止编码更改

Pet*_*ete 25 powershell encoding file-encodings

我正在进行一些搜索和替换操作,我正在尝试使用PowerShell进行自动化.不幸的是,我昨天认识到我们的代码库中有不同的文件编码(UTF8和ASCII).因为我们在不同的分支中执行这些搜索和替换操作,所以在此阶段我无法更改文件编码.

如果我正在运行以下行,它会将所有文件更改为UCS-2 Little Eindian,即使我的默认PowerShell编码设置为iso-8859-1(西欧(Windows)).

$content = Get-Content $_.Path
$content -replace 'myOldText' , 'myNewText' | Out-File $_.Path
Run Code Online (Sandbox Code Playgroud)

有没有办法阻止PowerShell更改文件的编码?

And*_*ndi 38

Out-File除非使用-Encoding参数覆盖,否则具有默认编码:

我为解决这个问题所做的是尝试通过读取它的字节顺序标记并将其用作-Encoding参数值来获取原始文件的编码.

这是一个处理一堆文本文件路径,获取原始编码,处理内容并使用原始编码将其写回文件的示例.

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
}
Run Code Online (Sandbox Code Playgroud)

更新此处是使用StreamReader类获取原始文件编码的示例.该示例读取文件的前3个字节,以便CurrentEncoding根据内部BOM检测例程的结果设置属性.

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

detectEncodingFromByteOrderMarks参数通过查看流的前三个字节来检测编码.如果文件以适当的字节顺序标记开头,它会自动识别UTF-8,little-endian Unicode和big-endian Unicode文本.否则,使用UTF8Encoding.有关更多信息,请参阅Encoding.GetPreamble方法.

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
Run Code Online (Sandbox Code Playgroud)

  • @Pete你将不得不得到编码.没有cmdlet可以为您提供.我更新了我的答案添加了一种不同的方法 两种方式都使用BOM检测. (2认同)