注意:以下内容适用于Windows PowerShell。请参阅下一节以了解跨平台的PowerShell Core版本。
在PSv5.1或更高版本上,其中>和>>是有效的别名Out-File,您可以通过首选项变量为>/ >>/ 设置默认编码Out-File$PSDefaultParameterValues:
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
在PSv5.0或更低版本上,您无法更改>/ 的编码>>,但是在PSv3或更高版本上,上述技术确实适用于Out-File。
($PSDefaultParameterValues首选项变量是PSv3.0中引入的)。
在PSv3.0或更高,如果你想设置的默认编码为所有支持的cmdlet
的-Encoding参数(在PSv5.1 +包括>和>>),使用:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
如果你在把这个命令$PROFILE一样,cmdlet等如Out-File和Set-Content将默认使用UTF-8编码,但请注意,这使得它的会话全局设置,将影响所有命令/脚本,没有明确指定编码。
同样,请确保在脚本或模块中包含要以相同方式运行的命令,以使即使在其他用户或其他计算机上运行时,它们的行为也确实相同。
警告:从v5.1开始,PowerShell 始终使用(伪)BOM创建UTF-8文件,这仅在Windows世界中很常见- 基于Unix的实用程序无法识别此BOM(请参阅底部)。
有关许多Windows PowerShell标准cmdlet的默认字符编码行为不一致的摘要,请参阅底部。
自动$OutputEncoding变量是不相关的,仅适用于PowerShell与外部程序通信的方式(PowerShell在向其发送字符串时使用的编码)-与输出重定向操作符和PowerShell cmdlet用于保存到文件的编码无关。
可选阅读:跨平台角度:PowerShell Core:
现在,PowerShell通过其PowerShell Core版本是跨平台的,明智地将其编码默认为无BOM的UTF-8,与类似Unix的平台一致。
这意味着不带BOM的源代码文件被假定为UTF-8,并且使用>/ Out-File/ Set-Content默认为无BOM的 UTF-8。显式使用utf8 -Encoding参数也会创建无BOM的 UTF-8,但是您可以选择使用具有该utf8bom值的伪BOM 创建文件。
如果您在类似Unix的平台上使用编辑器创建PowerShell脚本,并且如今甚至在Windows上使用诸如Visual Studio Code和Sublime Text之类的跨平台编辑器,则生成的*.ps1文件通常将不具有UTF-8伪BOM:
这在PowerShell Core上运行良好。
如果文件包含非ASCII字符,则在Windows PowerShell上可能会中断;如果确实需要在脚本中使用非ASCII字符,请使用BOM将它们另存为UTF-8 。
如果没有BOM,Windows PowerShell(mis)会将您的脚本解释为在旧版“ ANSI”代码页中编码(由Unicode之前的应用程序的系统语言环境确定;例如,在英语系统中为Windows-1252)。
相反,文件做有UTF-8的伪BOM可以在类Unix平台有问题的,因为它们会导致Unix工具,例如cat,sed和awk-甚至一些编辑器,例如gedit-到通过传递伪BOM,即把它当作数据。
这可能并不总是一个问题,但绝对可以,例如,当您尝试将文件读入bash带有text=$(cat file)或text=$(
Windows PowerShell中的默认编码行为不一致:
遗憾的是,Windows PowerShell中使用的默认字符编码完全不一致。上一节中讨论的跨平台PowerShell Core版本值得称赞并结束了这一点。
注意:
以下内容并不希望涵盖所有标准cmdlet。
在默认情况下,使用谷歌搜索cmdlet名称查找其帮助主题将向您显示主题的PowerShell Core版本;使用左侧主题列表上方的版本下拉列表可切换到Windows PowerShell版本。
在撰写本文时,文档经常错误地声称ASCII是Windows PowerShell中的默认编码-请参见此GitHub docs issue。
编写的 Cmdlet :
Out-File和>/ >>创建默认情况下的“ Unicode” 文件-UTF-16LE-其中每个ASCII范围字符(太)都由2个字节表示-与Set-Content/ 显着不同Add-Content(请参阅下一点);New-ModuleManifest并Export-CliXml创建UTF-16LE文件。
Set-Content(Add-Content如果文件尚不存在/为空)则使用ANSI编码(PowerShell调用的由活动系统区域设置的ANSI旧版代码页指定的编码Default)。
Export-Csv确实会创建ASCII文件,如记录所示,但请参阅-Append下面的注释。
Export-PSSession 默认情况下使用BOM创建UTF-8文件。
New-Item -Type File -Value 当前创建无物料清单(!)UTF-8。
该Send-MailMessage帮助主题还声称,ASCII编码是默认的-我没有亲自验证要求。
重新添加到现有文件的命令:
>>/ Out-File -Append让没有尝试匹配文件的的编码现有内容。也就是说,除非盲目地使用,否则他们会盲目地应用其默认编码,除非-Encoding这不是一个选项>>(除非在PSv5.1 +中通过间接$PSDefaultParameterValues显示,如上所示)。简而言之:您必须知道现有文件内容的编码,并使用相同的编码进行追加。
Add-Content是值得称赞的例外:在没有显式-Encoding参数的情况下,它会检测现有编码并将其自动应用于新内容。谢谢,js2010。请注意,在Windows PowerShell中,这意味着如果现有内容没有BOM,则将应用ANSI编码,而在PowerShell Core中则使用UTF-8。
这个GitHub问题中讨论了Out-File -Append/ >>和之间的这种不一致Add-Content,这也会影响PowerShell Core。
Export-Csv -Append 部分匹配现有编码:如果现有文件的编码是ASCII / UTF-8 / ANSI中的任何一种,则盲目追加UTF-8,但正确匹配UTF-16LE和UTF-16BE。
换句话说:在没有BOM的情况下,Export-Csv -Append假定UTF-8,而在Add-ContentANSI中。
读取的 Cmdlet(在没有BOM的情况下使用编码):
Get-Content并且Import-PowerShellDataFile默认为ANSI(Default),与一致Set-Content。
ANSI也是PowerShell引擎从文件中读取源代码时默认的默认值。
与此相反,Import-Csv,Import-CliXml和Select-String在不存在BOM的假设UTF-8。