我试图实现的应该是相当简单的,虽然Powershell试图使它很难。
我希望显示文件的完整路径,其中一些文件的名称中包含阿拉伯文、中文、日文和俄文字符
我总是得到一些无法辨认的输出,如下面所示的
在控制台中看到的输出正由另一个脚本使用。输出包含 ? 而不是实际字符。
执行的命令为
(Get-ChildItem -Recurse -Path "D:\test" -Include *unicode* | Get-ChildItem -Recurse).FullName
有没有简单的方法来启动powershell(通过命令行或任何可以写入脚本的方式),以便正确地看到输出。
我已经经历了许多类似的问题堆栈溢出,但他们都没有太多的输入以外,称之为Windows控制台子系统的问题。
7条答案
按热度按时间ssgvzors1#
注:
conhost.exe
提供的控制台窗口)的良好替代品,提供了卓越的Unicode字符支持。在Windows 11 22H2中,Windows终端甚至支持became the default console (terminal)。$OutputEncoding
、[Console]::InputEncoding
和[Console]::OutputEncoding
也很重要-参见下文。65001
(UTF-8);请注意,截至本文撰写之时,该特性仍处于测试阶段,使用它会产生深远的影响**-请参见this answer。$OutputEncoding
也设置为UTF-8(在Core中已默认为UTF-8),如下所示。在您的特定情况下-如果您必须支持阿拉伯语以及中文、日语和俄语字符-您唯一的选择是**
SimSun-ExtB
,该选项仅在Windows 10上可用**。请参阅Wikipedia以获取Windows字体针对哪些脚本(字母)的列表。
Properties
,然后切换到Fonts
选项卡并选择感兴趣的TrueType字体。65001
**,UTF-8代码页(通常使用chcp 65001
完成,但是不能直接在PowerShell会话[1]中使用,但下面的PowerShell命令具有相同的效果)。$OutputEncoding
首选项变量将管道输入 * 发送到 * 外部程序时(在解码 * 来自 * 外部程序的输出时,应用存储在[console]::OutputEncoding
中的编码)。Windows PowerShell中的以下神奇咒语可以做到这一点(如前所述,这 * 隐式 * 执行
chcp 65001
):$PROFILE
文件中。注:Windows 10的最新版本现在允许setting the system locale to code page
65001
(UTF-8)(该功能在Windows 10版本1903时仍处于测试阶段),这使得 * 所有 * 控制台窗口默认为UTF-8,包括Windows PowerShell的。如果您确实使用了该功能,则不再需要设置
[console]::InputEncoding
/[console]::OutputEncoding
,但您仍然需要设置$OutputEncoding
(在PowerShell * Core * 中不需要,因为$OutputEncoding
已经默认为UTF-8)。find.exe
和findstr.exe
,这些程序已在Windows 10中修复。*这些设置 * 仅适用于外部程序 *,与 *PowerShell的cmdlet * 在输出中使用的编码无关:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
添加到您的$PROFILE
,但请注意,这将影响会话中对具有-Encoding
参数的cmdlet的所有调用,除非显式使用该参数;另请注意,在 Windows PowerShell 中,您总是会获得 * 带有BOM* 的UTF-8文件;相反,在 PowerShell [Core] v6+ 中,默认为BOM-* 减去 * UTF-8(在没有-Encoding
和有-Encoding utf8
的情况下,您都必须使用'utf8BOM'
。可选背景信息
对eryksun的所有输入进行提示。
***当TrueType字体处于活动状态时 ,控制台窗口 * 缓冲区 * 正确地保留(非ASCII)Unicode字符,即使它们没有 * 正确地;也就是说,正如eryksun所指出的,即使它们可能一般地 * 出现 * 为
?
,以指示当前字体缺乏支持,您也可以 * 复制&粘贴 * 这样的字符到其他地方而不会丢失信息。*PowerShell能够将Unicode字符 * 输出到控制台 *,甚至无需先切换到代码页
65001
。然而,这本身并不保证其他程序可以正确处理这样的输出-见下文。
$OutputEncoding
首选项变量中指定的字符编码,该编码默认为ASCII(!),这意味着任何非ASCII字符都将转换为 literal?
字符,从而导致 * 信息丢失 *。(相比之下,PowerShell Core(v6+)现在一致使用(无BOM)UTF-8作为默认编码。)€: 1
,即使使用默认配置:node -pe "process.argv[1] + ': ' + process.argv[1].length" €
*
[Console]::OutputEncoding
:其结果是,如果需要从一个生成UTF-8的程序中 * 捕获输出 *,则还需要将
[Console]::OutputEncoding
设置为UTF-8;设置$OutputEncoding
仅覆盖 * 输入 *(到外部程序)方面。**
[Console]::InputEncoding
为控制台[2]中的 * 键盘输入 * 设置编码,并确定PowerShell's CLI如何解释通过 stdin(标准输入)接收的数据。***如果无法在 * 整个会话 * 中将控制台切换为UTF-8,则可以 * 暂时针对给定呼叫执行此操作:
*旧版本Windows(W10之前)上的问题:
chcp
的活动值65001
中断了某些外部程序的控制台输出,甚至中断了Windows旧版本中的批处理文件,这可能最终源于WriteFile()
Windows API函数中的错误(标准C库也使用),错误地报告了 * 字符 * 的数量,而不是 * 字节 * 的数量,代码页65001
有效,如X1 E10 F1 X中所讨论的。本机Windows控制台(终端)
conhost.exe
的上级替代产品eryksun建议了两个替代本机Windows控制台窗口(
conhost.exe
)的方法,由于使用了现代的、GPU加速的DirectWrite/DirectX API,而不是“无法处理复杂脚本、非BMP字符或自动回退字体的旧GDI实现”,因此提供了更好、更快的Unicode字符 * 渲染。[1]请注意,从PowerShell会话 * 内部 * 运行
chcp 65001
是 * 无效 * 的,因为.NET * 在启动时缓存 * 控制台的输出编码,并且不知道后来使用chcp
所做的更改(只拾取直接通过[console]::OutputEncoding]
所做的更改)。[2]我不清楚这在实践中如何体现;如果你知道,一定要告诉我们。
ffvjumwh2#
出于测试的目的,我创建了一些文件夹和文件,其中包含来自不同Unicode子范围的valid names,如下所示:
例如,使用 Courier New 控制台字体时,在PowerShell控制台中显示替换符号而不是CJK字符:
另一方面,使用SimSun控制台字体时,显示的是替换符号(可见性差),而不是阿拉伯语和希伯来语字符,而CJK字符似乎显示正确:
请注意,所有替换符号仅显示,而真实的字符将保留,如您在上面的PowerShell控制台中的以下 * 复制和粘贴 * 中所见:
为了完整起见,以下是Enable More Fonts for the Windows Command Prompt的相应注册表值(这也适用于Windows PowerShell控制台):
输出示例:
vhmi4jdf3#
如果您安装Microsoft's "Windows Terminal" from the Microsoft Store(或预览版),它会预先配置为完全Unicode本地化。
你仍然不能 * 输入命令 * 与特殊字符...除非你使用WSL!😍
a64a0gku4#
Powershell伊势是用于显示外来字符的选项:
korean.txt
是一个UTF8编码文件:e4yzc0pl5#
我也面临着类似的挑战,使用亚马逊翻译服务。我从Windows商店安装了终端,它现在对我有效了!
xt0899hw6#
确保安装了包含所有问题字符的字体,并将其设置为Win32控制台字体。如果我没记错的话,单击窗口左上角的PowerShell图标,然后选择“属性”。出现的弹出对话框应该有一个设置所用字体的选项。它可能必须是位图(
.FON
或.FNT
)字体。xhv8bpkk7#
刚刚注册只是为了澄清为什么“Lucida控制台”作为字体在Powershell伊势中工作的困惑.不幸的是,我无法评论,由于丢失的声誉,所以在这里作为答案:
在普通的Powershell中,所有字符都以配置的字体显示。这就是为什么中文或西里尔字符会被“Lucida Console”和许多其他字体打断。对于中文字符,Powershell伊势会自动将字体更改为“Dengxian”。
您可以通过将特殊字符复制到Word或能够显示不同字体的类似程序中,找到用于特殊字符的替代字体。