如何使用PowerShell将UTF-8字符传递给clip.exe而不转换为其他字符集?
我是Windows和Powershell的noobie。我来自Linux世界。我以前在如何使用PowerShell将UTF-8字符传递给clip.exe而不转换为其他字符集?,powershell,character-encoding,Powershell,Character Encoding,我是Windows和Powershell的noobie。我来自Linux世界。我以前在.bashrc中有一个小Bash函数,它可以复制一个“(”\_(ツ)_/“)为我将其粘贴到剪贴板,以便我可以将其粘贴到Slack之类的对话中 我的Bash别名如下:alias shruggie='printf''\_(ツ)_/“|xclip-选择c&&echo”\_(ツ)_/“” 我意识到这个问题很幼稚,但答案对我来说确实很有价值,因为我确信在将来的某个时候,我需要通过管道将非UTF-8字符输出到Powersh
.bashrc
中有一个小Bash函数,它可以复制一个“(”\_(ツ)_/“
)为我将其粘贴到剪贴板,以便我可以将其粘贴到Slack之类的对话中
我的Bash别名如下:alias shruggie='printf''\_(ツ)_/“|xclip-选择c&&echo”\_(ツ)_/“”
我意识到这个问题很幼稚,但答案对我来说确实很有价值,因为我确信在将来的某个时候,我需要通过管道将非UTF-8字符输出到Powershell脚本中
我在PowerShell配置文件中编写了此函数:
function shruggie() {
'¯\_(ツ)_/¯' | clip
Write-Host '¯\_(ツ)_/¯ copied to clipboard.' -foregroundcolor yellow
}
但是,当我在命令行上调用它时,这会给我:?\ \u(?)\ u/??
(未知的UTF-8字符转换为?
)
我已经看了一些,但我不知道如何将我的字符串转换为UTF-8,并将其通过
clip.exe
并从另一侧(剪贴板上)接收UTF-8.post Set Clipbord选项是最直接的答案,但正如PoSHv5和更高版本所指出的。然而,根据OP所使用的操作系统,并非所有的cmdlet在所有操作系统/PoSH版本上都可用。这并不是说Set Clipbord不可用,而是因为OP说它们是新的,这只是一个提示
如果您因任何原因无法访问,您可以创建自己的和/或使用附加模块。请参阅以下帖子:
使用上述文章中的“设置剪贴板”功能并修改OP文章以供使用的结果:
(Get-CimInstance -ClassName Win32_OperatingSystem).Caption
Microsoft Windows Server 2012 R2 Standard
$PSVersionTable
Name Value
---- -----
PSVersion 4.0
WSManStackVersion 3.0
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.42000
BuildVersion 6.3.9600.18773
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion 2.2
function Set-ClipBoard
{
Param
(
[Parameter(ValueFromPipeline=$true)]
[string] $text
)
Add-Type -AssemblyName System.Windows.Forms
$tb = New-Object System.Windows.Forms.TextBox
$tb.Multiline = $true
$tb.Text = $text
$tb.SelectAll()
$tb.Copy()
}
function New-Shruggie
{
Set-ClipBoard -text '¯\_(ツ)_/¯'
Write-Host '¯\_(ツ)_/¯ copied to clipboard.' -foregroundcolor yellow
}
New-Shruggie
¯\_(ツ)_/¯ copied to clipboard.
Results pasted from clipboard
¯\_(ツ)_/¯
不过,有以下几种选择,但以上仍然是最佳路线
首先请记住,输出由OS代码页和解释器(PoSH)控制,两者都默认为ASCII
通过查看内置变量的输出,可以查看高级默认CP设置
$OutputEncoding
正如时尚设计师杰弗里·斯诺弗所说:
当管道传输到现有可执行文件时,我们转换为ASCII的原因是当今大多数命令无法正确处理UNICODE。有些是,大多数不是 所以,所有这些都是说…你可以改变代码页,通过做像
[Console]::OutputEncoding
或者
$OutputEncoding = New-Object -typename System.Text.UTF8Encoding
如果将输出发送到文件
$OutPutData | Out-File $outFile -Encoding UTF8
如果您无法使用PowerShell 5的
设置剪贴板
功能(这是我的go-to解决方案),您可以以clip.exe
正确理解的方式对输出进行转换/编码
这里有两种方法可以实现您的愿望:
clip
这里的重要部分是将文件编码为:
Unicode
(这意味着使用
物料清单)$OutputEncoding
/[控制台]:OutputEncoding
有两个不同的独立方面:
- 正在复制
”\_(ツ)_/“”“使用
复制到剪贴板clip.exe将
- 写入(回音)
到控制台'\_(ツ)_/“
- 在没有BOM的情况下,Windows PowerShell将源代码解释为“ANSI”编码,指的是有效的传统单字节扩展ASCII代码页,如美国英语系统上的Windows-1252,因此会错误地解释UTF-8编码的源代码
- 请注意,相比之下,PowerShell Core使用UTF-8作为默认值,因此BOM不再是必需的(但仍然可以识别)
正在复制
”\_(ツ)_/“
到剪贴板,使用clip.exe
:
- 在Windows PowerShell v5.1+中,您可以使用内置的
cmdlet从PowerShell中将文本复制到剪贴板;由于PowerShell使用能够表示所有Unicode字符的.NETSet Clipboard
类型,因此不存在编码问题System.String
- 请注意,即使在Windows上运行,PowerShell Core也没有此cmdlet(从PowerShell Core v6.0.0-rc.2开始)
- 有关在早期PowerShell版本以及PowerShell核心中工作的剪贴板函数,请参阅我的
- 在早期版本的Windows PowerShell和PowerShell Core中,使用
,但使用需要额外的工作:clip.exe是一种可行的选择
创建一个无BOM的UTF16-LE编码,该编码New Object System.Text.Unicode编码$False,$False
可以理解clip.exe
- 不幸的是,解决问题需要使用magic
咒语;在PSv5+中,您可以使用以下方法绕过此错误:.psobject.BaseObject
[System.Text.unicode]::新建($False,$False)
- 不幸的是,解决问题需要使用magic
- 将该编码分配给首选项变量
可确保PowerShell使用该编码将数据传输到外部实用工具$OutputEncoding
clip.exe
写入
”\_(ツ)_/“
到控制台:
注意:Unix平台上的PowerShell Core通常使用默认编码为(无BOM)UTF-8的控制台(终端),因此不需要额外的工作
仅回显(打印)Unicode字符(超出8位范围),切换到可显示Unicode字符(超出扩展ASCI)的字体就足够了
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
function shruggie() {
[System.Text.Encoding]::Default.GetString(
[System.Text.Encoding]::UTF8.GetBytes('¯\_(ツ)_/¯')
) | clip.exe
Write-Host '¯\_(ツ)_/¯ copied to clipboard.' -foregroundcolor yellow
}
shruggie
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
}
$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding