注意:以下内容适用于Windows PowerShell。
请参阅下一节以了解跨平台的PowerShell Core(v6 +)版本。
在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(请参阅底部);有关创建无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创建文件。
如果您在类似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=$(<file)
-的字符串时,结果变量将包含伪BOM作为前3个字节。
Windows PowerShell中的默认编码行为不一致:
遗憾的是,Windows PowerShell中使用的默认字符编码完全不一致。上一节中讨论的跨平台PowerShell Core版本值得称赞并结束了这一点。
注意:
编写的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
当前创建无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。
这个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-Content
ANSI下。
Start-Transcript -Append
部分匹配现有的编码:它可以正确地将编码与BOM匹配,但是默认情况下会在没有编码的情况下默认为可能有损的ASCII编码。
读取的Cmdlet(即在没有BOM的情况下使用的编码):
Get-Content
并且Import-PowerShellDataFile
默认为ANSI(Default
),与一致Set-Content
。
ANSI也是PowerShell引擎从文件中读取源代码时默认的默认值。
相比之下,Import-Csv
,Import-CliXml
并Select-String
假定在不存在BOM的UTF-8。
>
/>>
成为有效的别名Out-File
吗?