jon*_*ell 6 powershell character-encoding
我是Windows和Powershell noobie.我来自Linux Land.我曾经在我的这个小Bash函数.bashrc中将一个" shruggie "(¯\_(?)_/¯)复制到剪贴板上,以便我可以将它粘贴到Slack上的对话等等.
我的Bash别名看起来像这样: alias shruggie='printf "¯\_(?)_/¯" | xclip -selection c && echo "¯\_(?)_/¯"'
我意识到这个问题是少年,但答案确实对我有价值,因为我确信我将需要在未来的某个时刻将非UTF-8字符输出到Powershell脚本中输出.
我在PowerShell配置文件中编写了这个函数:
function shruggie() {
'¯\_(?)_/¯' | clip
Write-Host '¯\_(?)_/¯ copied to clipboard.' -foregroundcolor yellow
}
Run Code Online (Sandbox Code Playgroud)
但是,当我在命令行上调用它时,这给了我:( ??\_(???)_/??未知的UTF-8字符被转换为?).
我已经查看了[System.Text.Encoding]::UTF8一些其他 问题,但我不知道如何将我的字符串转换为UTF-8并将其传递到clip.exe另一端(在剪贴板上)接收UTF-8.
有两个截然不同的独立方面:
¯\_(?)_/¯到剪贴板,用clip.exe¯\_(?)_/¯到控制台先决条件:PowerShell必须正确识别源代码的编码,以便下面的解决方案能够正常工作:如果您的源代码是UTF-8编码的,请务必将封装文件保存为UTF-8,其中包含用于Windows PowerShell的BOM以识别它.
在没有BOM的情况下,Windows PowerShell将源解释为"ANSI"编码,指的是有效的传统单字节扩展ASCII代码页,例如美国英语系统上的Windows-1252,因此会解释UTF-8编码的源代码不正确.
请注意,相比之下,PowerShell Core使用UTF-8作为默认值,因此不再需要BOM(但仍然可以识别).
¯\_(?)_/¯到剪贴板clip.exe:在Windows PowerShell v5.1 +中,您可以使用内置Set-Clipboardcmdlet从PowerShell中将文本复制到剪贴板; 鉴于PowerShell使用System.String能够表示所有 Unicode字符的.NET 类型,因此没有编码问题.
在早期版本的Windows PowerShell 和 PowerShell Core中,使用clip.exe是一种可行的替代方法,但其使用需要额外的工作:
function shruggie() {
$OutputEncoding = (New-Object System.Text.UnicodeEncoding $False, $False).psobject.BaseObject
'¯\_(?)_/¯' | clip
Write-Verbose -Verbose "Shruggie copied to clipboard." # see section about console output
}
Run Code Online (Sandbox Code Playgroud)
New-Object System.Text.UnicodeEncoding $False, $False创建一个BOM- 少 UTF16-LE编码,这clip.exe理解.
.psobject.BaseObject不幸的是,神奇的咒语需要解决一个bug ; 在PSv5 +中,您可以通过使用以下代码来绕过此错误:[System.Text.UnicodeEncoding]::new($False, $False)将该编码分配给首选项变量$OutputEncoding可确保PowerShell使用该编码将数据传输到外部实用程序clip.exe.
¯\_(?)_/¯到控制台:注意:Unix平台上的PowerShell Core通常使用默认编码为(无BOM)UTF-8的控制台(终端),因此不需要额外的工作.
仅仅回显(打印)Unicode字符(超出8位范围),切换到可以显示Unicode字符(超出扩展ASCII范围)的字体就足够了,因为,正如PetSerAl指出的那样,PowerShell使用Unicode版本WriteConsole要打印到控制台的Windows API函数.
要支持(大多数)Unicode字符,您最常切换到"TT"(TrueType)字体之一.
PetSerAl在一条评论中指出,Windows上的控制台窗口目前仅限于每个输出字符(单元格)一个16位代码单元; 鉴于仅(大部分)在所述字符BMP(基本多语种平面)是自包含的16位代码单元,超越BMP的(罕见)字符不能被表示.
遗憾的是,即使这对于某些(BMP)Unicode字符来说可能还不够,因为Unicode标准是版本化的,并且字体表示/实现可能会滞后.
事实上,与Windows 10发布ID 1703,只有少数的字体可以渲染 ?(Unicode字符KATAKANA LETTER TU,U+30C4UTF-8: E3 83 84):
MS GothicNSimSum请注意,如果您想(也)更改其他应用程序解释此类输出的方式,则必须再次设置$OutputEncoding:
例如,要使PowerShell期望从外部实用程序输入UTF-8 以及将UTF-8编码数据输出到外部实用程序,请使用以下命令:
$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
Run Code Online (Sandbox Code Playgroud)
以上隐含地将代码页更改为65001(UTF-8),如chcp(chcp.com)所示.
请注意,为了向后兼容,Windows控制台窗口仍默认为单字节,扩展ASCII旧版OEM代码页,例如437美国英语系统.
不幸的是,从v6.0.0-rc.2开始,这也适用于PowerShell Core,即使它已经切换到无BOM的UTF-8作为默认编码,也反映在$OutputEncoding.
| 归档时间: |
|
| 查看次数: |
2149 次 |
| 最近记录: |