默认情况下,当您将命令的输出重定向到文件或将其传递到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'}
设置,但我已经尝试了这个并没有效果。
https://blogs.msdn.microsoft.com/powershell/2006/12/11/outputencoding-to-the-rescue/谈到$OutputEncoding
乍一看似乎应该是相关的,但后来它谈到了用ASCII编码的输出,这不是实际发生的事情。
如何将PowerShell设置为使用UTF-8?
答案 0 :(得分:75)
注意:以下内容适用于 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
中,则为Out-File
和Set-Content
的cmdlet将使用UTF-8编码默认情况下,但请注意,这会使其成为会话全局设置,这将影响未明确指定编码的所有命令/脚本。
同样,确保在您希望以相同方式运行的脚本或模块中包含此类命令,以便即使在由其他用户或其他计算机运行时它们的行为也确实相同。
警告: PowerShell,从v5.1开始,总是创建带有(pseudo) BOM 的UTF-8文件 ,这在 Windows 世界中是惯用的 - 基于 Unix 的实用程序无法识别此BOM(请参见下图)。
有关许多Windows PowerShell标准cmdlet 中非常不一致的默认字符编码行为的摘要,请参阅底部。
自动$OutputEncoding
变量无关 ,仅适用于PowerShell与外部程序的通信方式(PowerShell使用的编码方式)向它们发送字符串时) - 它与输出重定向操作符和PowerShell cmdlet用于保存到文件的编码无关。
PowerShell is now cross-platform,通过其 PowerShell Core 版本,其编码 - 明智地 - 默认为无BOM的UTF-8 ,符合类Unix平台。
这意味着没有BOM的源代码文件被假定为UTF-8,而使用>
/ Out-File
/ Set-Content
默认为 BOM-少 UTF-8;明确使用utf8
-Encoding
参数也会创建 BOM-less UTF-8,但您可以选择使用伪BOM创建文件使用utf8bom
值。
如果您在类似Unix的平台上使用编辑器创建PowerShell脚本,现在甚至在 Windows 上使用跨平台编辑器(如Visual Studio Code和Sublime Text)创建PowerShell脚本,生成的{{ 1}}文件通常不具有UTF-8伪BOM:
相反,做的文件具有UTF-8伪BOM可能会在类Unix平台上出现问题,因为它们会导致诸如*.ps1
,{{{ 1}}和cat
- 甚至某些编辑器,例如sed
- 通过传递伪BOM,即将其视为数据
awk
中的字符串时,例如gedit
或bash
- 结果变量将伪BOM作为前3个字节。令人遗憾的是,Windows PowerShell中使用的默认字符编码非常不一致;正如前一节所讨论的,跨平台的PowerShell Core 版本已经值得称道地为此付出了代价。
注意:
以下内容并不希望涵盖所有标准cmdlet。
Google搜索cmdlet名称以查找其帮助主题现在默认显示主题的PowerShell Core 版本;使用左侧主题列表上方的版本下拉列表切换到 Windows PowerShell 版本。
在撰写本文时,文档经常错误地声称ASCII是Windows PowerShell中的默认编码 - 请参阅this GitHub docs issue。
写的Cmdlet:
text=$(cat file)
和text=$(<file)
/ Out-File
创建&#34; Unicode&#34; - UTF-16LE - 默认情况下的文件 - 其中每个ASCII范围字符(也)由 2 字节表示 - 这与>
/ >>
明显不同(见下一点); Set-Content
和Add-Content
也会创建UTF-16LE文件。
New-ModuleManifest
(如果文件尚未存在,则为Export-CliXml
/为空)使用ANSI编码(由活动系统区域设置和ANSI遗留代码页指定的编码, PowerShell调用Set-Content
)。
Add-Content
确实创建了ASCII文件,如文档所述,但请参阅下面的注释Default
。
Export-Csv
默认情况下会创建带有BOM的UTF-8文件。
-Append
目前创建无BOM(!)UTF-8。
Export-PSSession
帮助主题还声称ASCII编码是默认设置 - 我尚未亲自验证该声明。
将追加的命令发送到现有文件:
New-Item -Type File -Value
/ Send-MailMessage
让否尝试匹配文件现有内容的编码。
也就是说,他们盲目地应用他们的默认编码,除非>>
另有说明,这不是Out-File -Append
的选项(除了间接在PSv5.1 +中,通过-Encoding
,如上所示)。
简而言之:您必须知道现有文件内容的编码并使用相同的编码附加。
>>
是值得称赞的例外:如果没有明确的$PSDefaultParameterValues
参数,它会检测现有编码并自动将其应用于新内容。谢谢,js2010 。请注意,在Windows PowerShell中,这意味着如果现有内容没有BOM,则应用ANSI编码,而PowerShell Core中则为UTF-8。
在this GitHub issue中讨论Add-Content
/ -Encoding
和Out-File -Append
之间的不一致,这也会影响PowerShell Core 。
>>
部分与现有编码匹配:如果现有文件的编码是ASCII / UTF-中的任何一种,它会盲目附加 UTF-8 8 / ANSI,但正确匹配UTF-16LE和UTF-16BE
换句话说:在没有BOM的情况下,假设为UTF-8,而Add-Content
/ Export-Csv -Append
默认为ANSI。
读取 的Cmdlet(在缺少BOM时使用的编码):
Set-Content
和Add-Content
默认为ANSI(Get-Content
),与Import-PowerShellDataFile
一致。
相比之下,Default
,Set-Content
和Import-Csv
在没有BOM的情况下采用UTF-8 - 与Import-CliXml
和Select-String
答案 1 :(得分:2)
简而言之,使用:
write-output "your text" | out-file -append -encoding utf8 "filename"