考虑一个看起来像这样的文本文件:
This’s ISO-8859-1
This’s UTF-8
幕后,’
第一行中的花括号字符被编码为 ISO-8859-1,’
第二行中的相同字符被编码为 UTF-8
该文件如下所示cat -v
(-v
选项显示不可打印的字符):
$ cat -v testing.txt
ThisM-4s ISO-8859-1
ThisM-bM-^@M-^Ys UTF-8
目标是将文件标准化为 UTF-8,这意味着第一行需要更改,第二行不得更改。但是,如果您尝试使用 等将 ISO-8859-1 转换为 UTF-8 iconv
,recode
则会通过将 UTF-8’
转换为乱码字符来破坏文件的第二行
这是一个使用iconv
证明第二行被破坏的示例:
$ cat testing.txt | iconv -f iso-8859-1 -t utf-8
This´s ISO-8859-1
This’s UTF-8
recode
行为类似,修改第二行:
$ recode iso-8859-1..utf-8 testing.txt
$ cat testing.txt
This´s ISO-8859-1
This’s UTF-8
我想做的是跳过 UTF-8´
字符的转换(但仍将其传递给输出,不要将其剥离),因为它已经是 UTF-8,因此无需转换它
但我还没有找到任何方法来做到这一点
这个简化的文本文件仅用作示例——需要一个也适用于更大文件的解决方案
例如,文件可能在第 30、40、100’
行包含 UTF-8 字符;以及第’
50、60 和 200 行的 ISO-8859-1 字符。文件可能不包含 ISO-8859-1’
字符的任何实例(在这种情况下,不需要更改文件)。可以安全地假设该文件不会在同一行上同时包含 ISO-8859-1’
字符和 UTF-8’
字符,如果这会使问题范围更容易。
我看了这个问题: 如何有条件地重新编码为 UTF-8?
但是它似乎没有考虑文件包含混合 ISO-8859-1 和 UTF-8 的情况
是的,我知道在同一个文件中混合编码不是一个好主意
但它已经在几年前发生了,目标是把它全部清理干净,这样就不会再有问题了
Python 的 UTF-8 解码器可以将非 UTF-8 字符作为特殊代码点 U+DC00 – U+DCFF 传递(在 UTF-8 中通常是非法的)。之后可以找到它们并将其重新解码为其他内容:
您也可以手动操作:
.NET 允许您在默认选项旁边为无效字符创建自定义编码器/解码器(对无效字符抛出异常或将其替换为用户指定的字符串),因此您可以使用任何基于 .NET 的语言并编写自己的解码器进行转换ISO-8859-1 字符转换为 UTF-8。为此,我编写了一个简单的 PowerShell 脚本。如果没有,请将 PowerShell 安装到 Linux并将以下脚本另存为
convert.ps1
然后运行命令为
如果您想让它适用于 Windows-1252,那么只需更改
[char]::ConvertFromUtf32($bytesUnknown[0])
为[Text.Encoding]::GetEncoding(1252).GetString($bytesUnknown)[0]
样本输出:
请注意,
od -c
orhd
(默认情况下包含在大多数 Linux 发行版中)会比cat -v
它们更容易检查字节值要好得多欲了解更多信息,请阅读