如何在 Linux 上使用 iconv 命令
学习使用Linux iconv命令将文件转换为不同的字符编码
计算机通过将字符映射到不同的二进制值来存储字符。为了正确显示它们,您需要知道它们是如何编码的。 iconv 命令将文件转换为新的编码。
一直都是二进制
无论计算机使用或存储什么类型的数据,它都以二进制信息的形式保存。图像、文本、音乐、视频和其他所有内容都存储为二进制数据。无论数据位于存储设备上还是加载到计算机内存中,它仍然以二进制值表示。
如果数据是文本,并且我们想要在屏幕上显示该文本,则必须进行翻译以将二进制值转换为字符。为了执行翻译,我们需要知道创建数据时使用哪些值来表示每个字符。然后,软件可以向后工作并将存储的数值映射回字符。
由于成功取决于了解所使用的映射类型以及在数据创建和数据使用期间严格遵守映射规则,因此已经创建了规范此类字符映射的标准。如果我们直接理解行话,它们就很容易理解。
字符、字节和映射
字符是字母、数字或任何其他可显示的符号,例如标点符号、等号“=”和加号“+”等数学符号以及货币符号。您在屏幕上看到的代表该字母的东西称为字形,字形的集合构成了字体。
字体是很多人错误地称之为字体的东西。严格来说,字体是经过修改的字体版本,例如通过增加或减小其大小,或更改其粗细以使字形的线条更粗或更细。无论字体如何,字符的数字表示形式都保持不变。
单个映射中的所有字符称为字符集。集合中的每个字符都有自己的、固定的、唯一的数值,称为代码点。如果字符或符号没有出现在字符集中 - 也就是说,它没有代码点 - 则无法使用该字符集显示它。一个重要的考虑因素是用于表示单个字符的字节数。每个字符使用的字节越多,可以在集合中包含的字符就越多。
所有单字节字符集的鼻祖是 ASCII 标准。它起源于 20 世纪 60 年代末,当时制定了 7 位标准,对 128 个不同的代码点进行编码,供电传打字机使用。相比之下,Unicode 标准总共包含 1,114,112 个代码点。需要如此大的代码空间是因为 Unicode 试图为所有人类语言提供字符映射支持。
使用固定数量的字节来存储代码点是浪费的。如果一个代码点只需要一个字节来识别它,则为该代码点保留的其他字节是多余的。 Unicode 多字节可变长度字符集使用可变数量的字节作为代码点,描述复杂的代码点需要多达四个字节。
因此,一个代码点可能必须对两种类型的数据进行编码。它必须识别它所代表的字符,并且必须包含有关其自身的元数据,例如代码点中的字节数。此外,某些字符需要与其他字符组合才能获得最终的字形,因此代码点也需要对该信息进行编码。
可变长度方案的优点是您只使用真正需要的字节。这是有效的,并且会产生更小的文件。缺点是数据的读取和解析比较复杂。从一种字符集转换为另一种字符集可能会变得非常困难、非常快。
这就是 iconv 命令的用武之地。
如何使用 iconv 命令
iconv 命令在命令行选项方面的不足,在它支持的字符编码数量上得到了弥补。它列出了 1100 多种不同的编码,但许多都是同一事物的别名。我们可以使用 -l(列表)选项列出所有支持的编码。
iconv -l
要使用 iconv,您需要指定源文件和输出文件,以及要转换的编码和要转换的编码。如果不指定文件名,则 iconv 使用 STDIN 和 STDOUT,从命令行获取输入并将其输出写入终端窗口。您可以通过管道输入到 iconv,也可以将其输出重定向到文件。
我们将使用 iconv 和 STDIN 来说明一些要点。我们需要指定输入文本的编码,因此我们将使用 locale 命令来发现它是什么。
locale
第一行表示我们使用美国英语和 Unicode UTF-8 编码。我们的测试字符串包含一些纯文本、一个带重音的单词、一个非英语字符(德语 eszett 字符 ß)以及欧元的货币符号。
plain àccented non-English ß Foreign currency €
我们要把它转换成 ASCII。我们使用 echo 将输入文本传输到 iconv。我们使用 -f(from)选项指定输入编码为 UTF-8,使用 -t(to)选项指示我们希望输出采用 US-ASCII。
echo plain àccented non-English ß Foreign currency € | iconv -f UTF-8 -t US-ASCII
但在第一个障碍时就失败了。 US-ASCII 中没有与“à”等效的字符,因此放弃转换。 iconv 使用零偏移计数,因此我们得知问题发生在位置 6。如果我们添加 -c(继续)选项 iconv 将丢弃不可转换的字符并继续处理输入的其余部分。
echo plain àccented non-English ß Foreign currency € | iconv -f UTF-8 -t US-ASCII
该命令现已运行完成,但输出中缺少字符。我们可以让 iconv 通过替换相似的字符或其他表示来提供不可转换字符的近似值。如果它无法做到这一点,它会插入一个问号“?”所以你可以很容易地看到一个字符没有被转换。
此过程称为音译,要调用它,请将字符串“//TRANSLIT”附加到目标编码。
echo plain àccented non-English ß Foreign currency € | iconv -f UTF-8 -t US-ASCII//TRANSLIT
现在我们有了完整的输出文本,用“a”代替“à”,用“ss”代替“ß”,用“EUR”代替“€”货币符号。
将 iconv 与文件一起使用
对文件使用 iconv 与在命令行中使用它非常相似。要找出源文件的编码类型,我们可以使用file命令。
file -i input.txt
我们的输入文件采用 UTF-16LE 编码。这是一个 16 位小端编码。它看起来像这样:
less input.txt
如果你眯着眼睛阅读白色的字符,你就可以找出实际的文本字符串。很多软件会错误地将这样的文件视为二进制文件,因此我们将其转换为 UTF-8。
我们使用 -f(from)选项来指定输入文件的编码,并使用 -t(to)选项告诉 iconv 我们想要 UTF-8 的输出。我们需要使用 -o(输出)选项来命名输出文件。我们不使用选项来命名输入文件 - 我们只是告诉 iconv 它叫什么。
iconv -f UTF-16LE -t UTF-8//TRANSLIT input.txt -o output.txt
我们的输出文件如下所示:
less output.txt
当您需要时提供电力
你可能不会经常使用 iconv,但是当你确实需要它时,它可以拯救你的培根。
我收到了使用 Windows 或 Mac 计算机的用户(通常来自海外)发送的大量文件。它们以各种编码形式到达。我不止一次地祝福 iconv 让我可以轻松地在 Linux 上处理这些文件。