简答:
使用 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/1257(Baltic)和852/1250(中欧)。我想后者是因为koča 这个词听起来像是英语 hut、cabin 或 cottage 的常用斯拉夫语术语。
重现问题。下一个示例显示了OEM 和ANSI 代码页之间可能的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 ĚŠČŘŽÝÁÍÉ Ď Ť Ň
*****