about_Character_Encoding
简短说明
介绍 PowerShell 如何对字符串数据的输入和输出使用字符编码。
长说明
Unicode 是一种全球字符编码标准。 系统将 Unicode 专用于字符和字符串操作。 有关 Unicode 的各个方面的详细说明,请参阅 Unicode 标准。
Windows 支持 Unicode 和传统字符集。 Windows 代码页等传统字符集使用 8 位值或 8 位值的组合来表示特定语言或地理区域设置中使用的字符。
PowerShell 默认使用 Unicode 字符集。 但是,多个 cmdlet 具有 Encoding 参数,该参数可为不同字符集指定编码。 此参数允许你选择与其他系统和应用程序互操作所需的特定字符编码。
以下 cmdlet 具有 Encoding 参数:
- Microsoft.PowerShell.Management
- Add-Content
- Get-Content
- Set-Content
- Microsoft.PowerShell.Utility
- Export-Clixml
- Export-Csv
- Export-PSSession
- Format-Hex
- Import-Csv
- Out-File
- Select-String
- Send-MailMessage
字节顺序标记
字节顺序标记 (BOM) 是文件或文本流的前几个字节中的 Unicode 签名,它指示用于数据的 Unicode 编码。 有关详细信息,请参阅字节顺序标记文档。
在 Windows PowerShell 中,除 UTF7
之外的任何 Unicode 编码都是会创建 BOM。 PowerShell(v6 及更高版本)默认对所有文本输出都使用 utf8NoBOM
。
为了获得最佳的整体兼容性,请避免在 UTF-8 文件中使用 BOM。 Unix 平台和 Windows 平台上使用的 Unix 继承实用程序不支持 BOM。
同样,应避免使用 UTF7
编码。 UTF-7 不是标准的 Unicode 编码,在所有版本的 PowerShell 中都是不带 BOM 编写的。
在类 Unix 平台上创建 PowerShell 脚本或在 Windows 上使用跨平台编辑器(例如 Visual Studio Code)会生成使用 UTF8NoBOM
编码的文件。 这些文件在 PowerShell 中正常工作,但如果文件包含非 Ascii 字符,则可能会在 Windows PowerShell 中不起作用。
如果需要在脚本中使用非 Ascii 字符,请将它们保存为带有 BOM 的 UTF-8 文件。 如果没有 BOM,Windows PowerShell 会将脚本误解为是在旧的“ANSI”代码页中编码的。 相反,具有 UTF-8 BOM 的文件在类 Unix 平台上可能会出现问题。 许多 Unix 工具(如 cat
、sed
、awk
)以及一些编辑器(如 gedit
)不知道如何处理 BOM。
Windows PowerShell 中的字符编码
在 PowerShell 5.1 中,Encoding 参数支持以下值:
Ascii
使用 Ascii(7 位)字符集。BigEndianUnicode
将 UTF-16 与 big-endian 字节顺序配合使用。BigEndianUTF32
将 UTF-32 与 big-endian 字节顺序配合使用。Byte
将一组字符编码为一个字节序列。Default
使用与系统的活动代码页(通常是 ANSI)对应的编码。Oem
使用与系统的当前 OEM 代码页对应的编码。String
与Unicode
相同。Unicode
将 UTF-16 与 little-endian 字节顺序配合使用。Unknown
与Unicode
相同。UTF32
将 UTF-32 与 little-endian 字节顺序配合使用。UTF7
使用 UTF-7。UTF8
使用 UTF-8(带 BOM)。
一般而言,Windows PowerShell 默认使用 Unicode UTF-16LE 编码。 但是,Windows PowerShell 中 cmdlet 使用的默认编码不一致。
注意
使用除 UTF7
之外的任何 Unicode 编码都是会创建 BOM。
对于将输出写入文件的 cmdlet:
Out-File
以及重定向运算符>
和>>
会创建 UTF-16LE 文件,这与Set-Content
和Add-Content
明显不同。New-ModuleManifest
和Export-CliXml
也会创建 UTF-16LE 文件。当目标文件为空或不存在时,
Set-Content
和Add-Content
使用Default
编码。Default
是由活动系统区域设置的 ANSI 旧代码页指定的编码。Export-Csv
会创建Ascii
文件,但在使用 Append 参数时会使用不同的编码(请参阅下文)。默认情况下,
Export-PSSession
会创建带有 BOM 的 UTF-8 文件。New-Item -Type File -Value
会创建不带 BOM 的 UTF-8 文件。默认情况下,
Send-MailMessage
使用Ascii
编码。Start-Transcript
会创建带有 BOM 的Utf8
文件。 使用 Append 参数时,编码可能有所不同(请参阅下文)。
对于追加到现有文件的命令:
Out-File -Append
和>>
重定向运算符不会尝试匹配现有目标文件内容的编码。 除非使用 Encoding 参数,否则它们将使用默认编码。 追加内容时必须使用文件原始编码。如果没有显式 Encoding 参数,
Add-Content
会检测现有编码并自动将其应用到新内容。 如果现有内容没有 BOM,则会使用Default
ANSI 编码。Add-Content
的行为与 PowerShell(v6 及更高版本)中的行为相同,只是默认编码为Utf8
。当目标文件包含 BOM 时,
Export-Csv -Append
与现有编码匹配。 如果没有 BOM,它将使用Utf8
编码。Start-Transcript -Append
与包含 BOM 的文件的现有编码匹配。 如果没有 BOM,则默认为Ascii
编码。 当脚本中的数据包含多字节字符时,此编码可能会导致数据丢失或字符损坏。
对于在没有 BOM 的情况下读取字符串数据的 cmdlet:
Get-Content
和Import-PowerShellDataFile
使用Default
ANSI 编码。 PowerShell 引擎从文件读取源代码时也使用 ANSI。在没有 BOM 的情况下,
Import-Csv
、Import-CliXml
和Select-String
采用Utf8
。
PowerShell 中的字符编码
在 PowerShell(v7.1 及更高版本)中,Encoding 参数支持以下值:
ascii
:对 ASCII(7 位)字符集使用编码。ansi
:对当前区域性的 ANSI 代码页使用编码。 此选项是在 PowerShell 7.4 中添加的。bigendianunicode
:使用 big-endian 字节顺序以 UTF-16 格式进行编码。bigendianutf32
:使用 big-endian 字节顺序以 UTF-32 格式进行编码。oem
:对 MS-DOS 和控制台程序使用默认编码。unicode
:使用 little-endian 字节顺序以 UTF-16 格式进行编码。utf7
:采用 UTF-7 格式编码。utf8
:采用 UTF-8 格式(无 BOM)进行编码。utf8BOM
:使用字节顺序标记 (BOM) 以 UTF-8 格式进行编码utf8NoBOM
:不使用字节顺序标记 (BOM) 以 UTF-8 格式进行编码utf32
:使用 little-endian 字节顺序以 UTF-32 格式进行编码。
PowerShell 默认对所有输出都使用 utf8NoBOM
。
从 PowerShell 6.2 开始,Encoding 参数还允许注册代码页的数字 ID(如 -Encoding 1251
)或已注册代码页的字符串名称(如 -Encoding "windows-1251"
)。 有关详细信息,请参阅 Encoding.CodePage .NET 文档。
从 PowerShell 7.4 开始,可以使用 Encoding 参数的 Ansi
值来传递当前区域性 ANSI 代码页的数字 ID,而无需手动指定它。
更改默认编码
PowerShell 有两个可用于更改默认编码行为的默认变量。
$PSDefaultParameterValues
$OutputEncoding
有关详细信息,请参阅 about_Preference_Variables。
从 PowerShell 5.1 开始,重定向运算符(>
和 >>
)调用 Out-File
cmdlet。 因此,可以使用 $PSDefaultParameterValues
首选项变量设置它们的默认编码,如以下示例所示:
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
使用以下语句可更改具有 Encoding 参数的所有 cmdlet 的默认编码。
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
重要
将此命令放入 PowerShell 配置文件中会使首选项成为会话全局设置,该设置会影响未显式指定编码的所有命令和脚本。
同样,应该在你希望行为方式与此相同的脚本或模块中包含这样的命令。 使用这些命令可确保 cmdlet 的行为方式与此相同,即使由其他用户、在不同计算机上或在不同版本的 PowerShell 中运行也是如此。
自动变量 $OutputEncoding
影响 PowerShell 用于与外部程序通信的编码。 它不会影响输出重定向运算符和 PowerShell cmdlet 用于保存到文件的编码。