【问题标题】:console command & output to unicode控制台命令和输出到 unicode
【发布时间】:2016-12-13 21:13:22
【问题描述】:

我知道,这是一个老问题,但我找到的答案在以下情况下都没有帮助:

fc /u TextA.txt TextB.txt

比较两个 Unicode 编码的 txt 文件并在屏幕上正确显示结果 (!)。

正如所料,

fc /u TextA.txt TextB.txt > Comp.txt

不会生成 Unicode 编码文件。

不幸的是在类似情况下使用的方法

cmd /u /c fc /u TextA.txt TextB.txt > Comp.txt

不起作用,生成的文件是 ANSI 编码的。

我希望这里有人可以帮助...

已编辑(在第一次 cmets 之后):问题似乎是 cmd /u(或 chcp)仅适用于“内部”命令(如 dir)。 fc 不是内部命令...(感谢 LotPings!)

【问题讨论】:

  • @Fabre:第一个例子没有区别,第二个似乎语法不正确。 -- 我不知道如何在这里发布文件...但是您可以简单地在记事本中写一个单词并将文件保存为 Unicode,第二个文件也是如此,然后查看 Comp.txt 是 Unicode 还是 ANSI 编码的。
  • 嘿,你是对的!你不要忘记谁在这里解决了问题:) 非常非常好的一点。值得一点东西。
  • 好吧,我被困住了,就像你一样。 cmd /u 似乎不起作用!
  • @Jean-FrançoisFabre cmd /? 声明 /U Causes the output of **internal** commands to a pipe or file to be Unicode IMO Fc.exe 不是内部的。最终这对how-to-make-unicode-charset-in-cmd-exe-by-default 有帮助,即使输出是 UTF8,您也可以转换为您喜欢的 UTF
  • 似乎是fc 中的一个缺陷。不确定您能做些什么。

标签: unicode cmd windows-console


【解决方案1】:

简答

使用 PowerShell 的Compare-Object cmdlet 如下:

Compare-Object  (Get-Content ".\fileA.txt") (Get-Content ".\fileB.txt")

基本自定义输出到文件:

Compare-Object (Get-Content ".\fileA.txt") (Get-Content ".\fileB.txt") |
  Format-Table -Property SideIndicator, InputObject -AutoSize -HideTableHeaders -Wrap |
    Out-File .\fileAB.txt -Encoding unicode

Compare-Object (Get-Content ".\fileA.txt") (Get-Content ".\fileB.txt") -PassThru |
    Out-File .\fileAB.txt -Encoding unicode

原始答案(另请参阅下面的修正):

č 字母(带有 Caron 的拉丁小写字母 C,代码点 U+010D)出现在代码页 775/1257Baltic)和852/1250中欧)。我想后者是因为koča 这个词听起来像是英语 hutcabincottage 的常用斯拉夫语术语。

重现问题。下一个示例显示了OEMANSI 代码页之间可能的mojibake 情况;显然,cmd.exe 本身进行了一些隐式(以及不清楚)字符代码转换:

D:\test\Unicode> powershell -c "'fileA','fileB'|ForEach-Object {$_; Get-Content .\$_.txt}"
fileA
a lc ěščřžýáíé ď ť ň
a UC ĚŠČŘŽÝÁÍÉ Ď Ť Ň
fileB
b lc ěščřžýáíé ď ť ň
b UC ĚŠČŘŽÝÁÍÉ Ď Ť Ň

D:\test\Unicode> chcp
Active code page: 1250

D:\test\Unicode> fc.exe /U .\fileA.txt .\fileB.txt > .\CompAB_1250.txt

D:\test\Unicode> type .\CompAB_1250.txt
Comparing files .\fileA.txt and .\FILEB.TXT
***** .\fileA.txt
a lc Řçźý§ě ˇ‚ Ô ś ĺ
a UC ·ć¬ü¦íµÖ Ň › Ő
***** .\FILEB.TXT
b lc Řçźý§ě ˇ‚ Ô ś ĺ
b UC ·ć¬ü¦íµÖ Ň › Ő
*****

cmd 修复:

D:\test\Unicode> chcp 852
Active code page: 852

D:\test\Unicode> fc.exe /U .\fileA.txt .\fileB.txt > .\CompAB_852.txt

D:\test\Unicode> type .\CompAB_852.txt
Comparing files .\fileA.txt and .\FILEB.TXT
***** .\fileA.txt
a lc ěščřžýáíé ď ť ň
a UC ĚŠČŘŽÝÁÍÉ Ď Ť Ň
***** .\FILEB.TXT
b lc ěščřžýáíé ď ť ň
b UC ĚŠČŘŽÝÁÍÉ Ď Ť Ň
*****

在上面的例子中,CompAB_1250.txt(乱码)和CompAB_852.txt(有效)都被编码在一个单字节的代码页中。要获取 Unicode 输出,请使用 PowerShell,如下所示:

PowerShell 修复 #1。强制PowerShell 从命令行使用代码页852(在调用powershell 之前显式使用chcp 852 命令):

D:\test\Unicode> chcp 852
Active code page: 852

D:\test\Unicode> powershell -c ". fc.exe /U .\fileA.txt .\fileB.txt > .\CompAB.txt"

D:\test\Unicode> powershell -c "'CompAB' | ForEach-Object {$_; Get-Content .\$_.txt}"
CompAB
Comparing files .\fileA.txt and .\FILEB.TXT
***** .\fileA.txt
a lc ěščřžýáíé ď ť ň
a UC ĚŠČŘŽÝÁÍÉ Ď Ť Ň
***** .\FILEB.TXT
b lc ěščřžýáíé ď ť ň
b UC ĚŠČŘŽÝÁÍÉ Ď Ť Ň
*****

PowerShell 修复 #2 强制 PowerShell 使用代码页 852 即时 无论活动控制台代码页如何并保持后者不变(例如,选择了1252 代码页,不包含大部分使用过的字母):

D:\test\Unicode> chcp 1252
Active code page: 1252

D:\test\Unicode> powershell -c "[System.Console]::OutputEncoding=[System.Text.ASCIIEncoding]::GetEncoding(852);. fc.exe /U .\fileA.txt .\fileB.txt > .\CompAB.txt"

D:\test\Unicode> powershell -c "'CompAB' | ForEach-Object {$_; Get-Content .\$_.txt}"
CompAB
Comparing files .\fileA.txt and .\FILEB.TXT
***** .\fileA.txt
a lc ěščřžýáíé ď ť ň
a UC ĚŠČŘŽÝÁÍÉ Ď Ť Ň
***** .\FILEB.TXT
b lc ěščřžýáíé ď ť ň
b UC ĚŠČŘŽÝÁÍÉ Ď Ť Ň
*****

D:\test\Unicode> chcp
Active code page: 1252

从新打开的cmd 窗口运行下一个命令以获取进一步解释:

powershell -c "[console]::OutputEncoding"
chcp 1252
powershell -c "[console]::OutputEncoding"
chcp 1250
powershell -c "[console]::OutputEncoding"
chcp 852
powershell -c "[console]::OutputEncoding"
rem etc. etc. etc.

编辑(修正):最终在输入文件中添加了一些希腊字符进行了测试; fc.exe 从命令行 fc.exe /U .\fileA.txt .\fileB.txt 甚至从 Powershell 输出看起来都很好:

D:\test\Unicode> powershell -c ". fc.exe /U .\fileA.txt .\fileB.txt"
Comparing files .\fileA.txt and .\FILEB.TXT
***** .\fileA.txt
a lc ěščřžýáíé ď ť ň
a    Ελληνικά  ΕΛΛΗΝΙΚΆ
a UC ĚŠČŘŽÝÁÍÉ Ď Ť Ň
***** .\FILEB.TXT
b lc ěščřžýáíé ď ť ň
b    Ελληνικά  ΕΛΛΗΝΙΚΆ
b UC ĚŠČŘŽÝÁÍÉ Ď Ť Ň
*****

但是,> 将上述输出重定向到文件以及将| 管道传输到另一个 cmdlet 会导致信息丢失,因此某些字符要么出现乱码(通过 mojibake),要么至少被 @987654360 替换@问号,例如如下:

PS D:\test\Unicode> . fc.exe /U .\fileA.txt .\fileB.txt | ForEach-Object {$_}
Comparing files .\fileA.txt and .\FILEB.TXT
***** .\fileA.txt
a lc ěščřžýáíé ď ť ň
a    ????????  ????????
a UC ĚŠČŘŽÝÁÍÉ Ď Ť Ň
***** .\FILEB.TXT
b lc ěščřžýáíé ď ť ň
b    ????????  ????????
b UC ĚŠČŘŽÝÁÍÉ Ď Ť Ň
*****

【讨论】:

  • 哇,哇,哇!非常感谢您的深入分析!但是,如果我正确理解您的方法,这不是“unicode 解决方案”
  • 哇,哇,哇!非常感谢您的深入分析!但是,如果我正确理解您的方法,这不是“unicode 解决方案”。我仅以koča 为例。 “现实生活”中的文件不仅可以包含来自cp 852 的字符,还可以包含来自整个 unicode 的字符。
  • @newbieforever cmd 中没有 "unicode 解决方案",因为 cmd 不完全识别 unicode,基本上遵循 CHAR_INFO structure。答案已更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-14
  • 2019-03-11
  • 2016-06-05
  • 1970-01-01
  • 2012-12-13
  • 1970-01-01
  • 2011-02-20
相关资源
最近更新 更多