默认情况下,当您将命令的输出重定向到文件或将其通过管道传递到PowerShell中的其他内容时,编码为UTF-16,这没有用。我希望将其更改为UTF-8。

可以根据具体情况通过将>foo.txt语法替换为| out-file foo.txt -encoding utf8来完成,但这很麻烦每次都要重复。

在PowerShell中进行设置的持久方法是将它们放在\Users\me\Documents\WindowsPowerShell\profile.ps1中;我已验证此文件确实在启动时执行。

据说可以使用$PSDefaultParameterValues = @{'Out-File:Encoding' = 'utf8'}设置输出编码,但我已经尝试过了,但没有效果。

讨论$OutputEncoding的https://blogs.msdn.microsoft.com/powershell/2006/12/11/outputencoding-to-the-rescue/乍一看似乎应该是相关的,但随后谈论输出是用ASCII编码的,这实际上并没有发生。

如何设置PowerShell使用UTF-8?

#1 楼

注意:以下内容适用于Windows PowerShell。
请参阅下一节以了解跨平台PowerShell Core(v6 +)版本。


在PSv5.1或更高版本上,其中>>>实际上是Out-File的别名,您可以通过>首选项变量设置>> / Out-File / $PSDefaultParameterValues的默认编码:

$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'




在PSv5.0或更低版本上,您无法更改> / >>的编码,但是在PSv3或更高版本上,上述技术确实适用于对Out-File的显式调用。
(在PSv3中引入了$PSDefaultParameterValues首选项变量。 0)。


在PSv3.0或更高版本上,如果要为所有支持-Encoding参数的cmdlet设置默认编码(PSv5.1 +中包括>>>),请使用:

$PSDefaultParameterValues['*:Encoding'] = 'utf8'



如果将此命令放在$PROFILE中,则Out-FileSet-Content等cmdlet将使用UTF -8厘米默认情况下会编码,但是请注意,这会使它成为一个全局会话设置,将影响所有未明确指定编码的命令/脚本。
同样,请确保在所需的脚本或模块中包含此类命令行为相同,即使在由另一个用户或另一台计算机运行时,它们的行为也确实相同。
警告:PowerShell从v5.1开始,始终使用(伪)BOM_创建UTF-8文件_ ,这仅在Windows世界中很常见-基于Unix的实用程序无法识别此BOM(请参阅底部);有关创建无BOM的UTF-8文件的变通办法,请参阅此文章。
有关许多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创建文件。


如果创建PowerShell脚本使用类似Unix的平台上的编辑器,如今甚至在具有跨平台编辑器(例如Visual Studio Code和Sublime Text)的Windows上,生成的*.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平台上可能会出现问题,因为它们会导致诸如catsedawk之类的Unix实用程序-甚至是诸如gedit之类的一些编辑器-都将伪BOM传递通过,即将其视为数据。 br />
这可能并不总是一个问题,但绝对可以,例如,当您尝试将文件读入bash中的字符串时,例如text=$(cat file)text=$(<file)-结果变量将包含伪BOM作为前3个字节。





Windows PowerShell中的默认编码行为不一致:
遗憾的是,Windows PowerShell中使用的默认字符编码完全不一致。值得赞扬的是,上一节中讨论的跨平台PowerShell Core版本已经结束。
注意:


以下内容并不希望涵盖所有内容。标准cmdlet。


谷歌搜索cmdlet名称以查找其帮助主题,现在默认情况下会向您显示主题的PowerShell Core版本;使用左侧主题列表上方的版本下拉列表切换到Windows PowerShell版本。


撰写本文时,文档经常错误地声称ASCII是默认设置。 Windows PowerShell中的编码-请参见此GitHub文档问题。



编写以下内容的cmdlet:
Out-File> / >>创建“ Unicode”-UTF-16LE-文件默认情况下-每个ASCII范围字符(太)都由2个字节表示-与Set-Content / Add-Content明显不同(请参阅下一点); New-ModuleManifestExport-CliXml还会创建UTF-16LE文件。
Set-Content(如果文件尚不存在/为空,则为Add-Content)使用ANSI编码(由活动系统语言环境的ANSI旧代码页面指定的编码,PowerShell会调用该编码) Default)。如所记录的那样,Export-Csv确实创建了ASCII文件,但请参阅以下有关-Append的注释。
Export-PSSession默认情况下使用BOM创建UTF-8文件。
New-Item -Type File -Value当前创建了无BOM的( !)UTF-8。
Send-MailMessage帮助主题还声称ASCII编码是默认设置-我尚未亲自验证该声明。
Start-Transcript始终使用BOM表创建UTF-8文件,但请参阅以下有关-Append的注释。
重新添加到现有文件的命令:
>> / Out-File -Append不会尝试匹配文件现有内容的编码。
也就是说,除非-Encoding另有说明,否则它们会盲目应用其默认编码,而>>则不可选(除非在PSv5.1 +中通过$PSDefaultParameterValues间接提供,如上所示)。
简短:您必须知道现有文件内容的编码并使用相同的编码进行追加。
Add-Content是值得称赞的例外:在没有显式-Encoding参数的情况下,它会检测到现有编码并将其自动应用于新编码内容。谢谢,js2010。请注意,在Windows PowerShell中,这意味着如果现有内容没有BOM,则将应用ANSI编码,而在PowerShell Core中则使用UTF-8。
Out-File -Append / >>Add-Content之间的不一致,这也会影响PowerShell核心,将在此GitHub问题中讨论。
Export-Csv -Append部分匹配现有编码:如果现有文件的编码是ASCII / UTF-8 / ANSI中的任何一种,它会盲目附加UTF-8,但正确匹配UTF-16LE和UTF -16BE。
换句话说:在没有BOM的情况下,Export-Csv -Append假定UTF-8是,而Add-Content假定ANSI。
Start-Transcript -Append部分匹配现有的编码:它与BOM正确匹配编码,但是

读取的Cmdlet(即没有BOM时使用的编码):
Get-ContentImport-PowerShellDataFile默认为ANSI(Default ),与Set-Content一致。
ANSI也是PowerS地狱引擎本身默认为从文件中读取源代码的时间。
相比之下,在没有BOM的情况下,Import-CsvImport-CliXmlSelect-String假定为UTF-8。

评论


有什么方法可以强制在Win10上不添加BOM表?

–mvorisek
19年1月30日,0:27

我不同意@EliaWeiss,但它专门用于Windows PowerShell,最终他们确实在PowerShell Core中做到了。

–mklement0
19年4月12日在16:38

@Marc:值得称赞的是VS Code和其他现代跨平台编辑器默认使用UTF-8,但这意味着它们会误解ANSI编码的文件。记事本使用试探法来猜测编码。关键在于,这只是一个猜测,因为任何UTF-8编码的文件也是技术上有效的ANSI编码的文件(反之亦然)。如果没有像Unix平台那样的BOM,Windows上的所有内容都默认为UTF-8,那就太好了,但是事实并非如此,尤其是在Windows PowerShell中,尽管幸运的是,现在在PowerShell Core中就是这种情况。

–mklement0
19-4-17在22:16



要查看当前值(如果有的话),只需键入$ PSDefaultParameterValues

–桑德堡
19年11月7日在13:53

@ not2qubit:chcp报告的内容仅取决于[Console] :: InputEncoding。由于.NET的编码缓存,因此无法从PowerShell内部使用chcp.com,但可以在cmd.exe中使用它,如果稍后从那里启动PowerShell,它也将很有效。

–mklement0
12月18日21:25

#2 楼

简而言之,请使用:

write-output "your text" | out-file -append -encoding utf8 "filename"