Powershell 和 UTF-8

Powershell and UTF-8

我有一个 html 文件 test.html 使用 atom 创建,其中包含:

Testé encoding utf-8

当我使用 Powershell 控制台读取它时(我使用的是法语 Windows)

Get-Content -Raw test.html

我回来了:

Testé encoding utf-8

为什么重音字符打印不正确?

# Created a UTF-8 Sig File 
notepad .\test.html

# Get File contents with/without -raw
cat .\test.html;Get-Content -Raw .\test.html
Testé encoding utf-8
Testé encoding utf-8

# Check Encoding to make sure
Get-FileEncoding .\test.html
utf8

如您所见,它在 Windows10 上的 PowerShell v5 中绝对有效。我会仔细检查文件格式和您创建的文件的内容,因为可能引入了您的字符编辑器可能不会接。

如果您的 PowerShell 中没有 Get-FileEncoding 作为 cmdlet,这里有一个实现,您可以 运行:

function Get-FileEncoding([Parameter(Mandatory=$True)]$Path) {
    $bytes = [byte[]](Get-Content $Path -Encoding byte -ReadCount 4 -TotalCount 4)

    if(!$bytes) { return 'utf8' }

    switch -regex ('{0:x2}{1:x2}{2:x2}{3:x2}' -f $bytes[0],$bytes[1],$bytes[2],$bytes[3]) {
        '^efbbbf'   {return 'utf8'}
        '^2b2f76'   {return 'utf7'}
        '^fffe'     {return 'unicode'}
        '^feff'     {return 'bigendianunicode'}
        '^0000feff' {return 'utf32'}
        default     {return 'ascii'}
    }
}
  • 默认情况下 Atom editor creates UTF-8 files without a pseudo-BOM(从跨平台的角度来看,这是正确的做法)。

  • Windows PowerShell[1] 只识别 UTF-8 文件 伪BOM.

    • 在没有伪 BOM 的情况下,PowerShell 将文件解释为根据系统的遗留 ANSI 代码页,例如美国系统上的 Windows-1252,对于实例。
      (这也是记事本使用的默认编码,它称为“ANSI”,不仅在读取文件时,而且在创建文件时也是如此。 Windows PowerShell 的 Get-Content / Set-Content 同上(此编码称为 Default 并且是实际默认值,因此无需指定);相比之下,Out-File / > 默认创建 UTF-16LE编码文件(Unicode)。)

因此,为了 Get-Content 在 [=72] 中正确识别 BOM-less UTF-8 文件 =] PowerShell,你必须使用-Encoding utf8.


[1] 相比之下,跨平台 PowerShell Core 版本值得称赞 默认 为 UTF-8,在 cmdlet 中一致,无论是在阅读和写作,所以即使没有 BOM,它也能正确解释 UTF-8 编码的文件,并且默认情况下也创建没有 BOM 的文件。