如何在 Linux 上使用 iconv 命令

计算机通过将字符映射到不同的二进制值来存储字符。要正确显示它们,您需要知道它们是如何编码的。iconv 命令将文件转换为新编码。

它一直都是二进制的

无论计算机处理或存储什么类型的数据,它都以二进制信息的形式保存。图像、文本、音乐、视频和其他所有内容都存储为二进制数据。无论数据是在存储设备上还是加载到计算机的内存中,它仍然由二进制值表示。

如果数据是文本,并且我们想在屏幕上显示该文本,则必须进行翻译才能将二进制值转换为字符。要执行转换,我们需要知道创建数据时使用了哪些值来表示每个字符。然后,软件可以向后工作并将存储的数值映射回字符。

由于成功取决于了解使用了哪种类型的映射,并在数据创建和数据使用过程中严格遵守映射规则,因此已经创建了将此类字符映射形式化的标准。如果我们把行话弄清楚,它们很容易理解。

字符、字节和映射

字符是字母、数字或任何其他可显示的符号,例如标点符号、数学符号(如等于“=”和加“+”)以及货币符号。您在屏幕上看到的表示该字母的内容称为字形,而字形集合构成了字体。

字体是很多人错误地称之为字体。严格来说,字体是经过修改的字体版本,例如通过增加或减少其大小,或更改其粗细以使字形的线条变粗或变细。无论字体如何,字符的数字表示形式都保持不变。

单个映射中的所有字符称为字符集。集合中的每个字符都有自己的固定唯一数值,称为码位。如果字符或符号未出现在字符集中(即,没有代码点),则无法使用该字符集显示该字符或符号。一个重要的考虑因素是用于表示单个字符的字节数。每个字符使用的字节数越多,集合中可以包含的字符就越多。

所有单字节字符集的祖父是 ASCII 标准。它起源于 1960 年代后期,当时制定了 7 位标准,该标准编码了 128 个不同的代码点供电传打印机使用。相比之下,Unicode 标准总共包含 1,114,112 个码位。需要如此大的代码空间,因为 Unicode 尝试为所有人类语言提供字符映射支持。

使用固定数量的字节来存储代码点是浪费。如果代码点只需要一个字节来标识它,则为该代码点保留的其他字节是冗余的。Unicode 多字节可变长度字符集对代码点使用可变数量的字节,描述复杂的代码点需要多达四个字节。

因此,代码点可能必须对两种类型的数据进行编码。它必须标识它所表示的字符,并且必须包含有关自身的元数据,例如代码点中的字节数。此外,某些字符需要与其他字符组合才能获得最终字形,因此代码点也需要对该信息进行编码。

可变长度方案的优点是只使用真正需要的字节。这是有效的,并导致较小的文件。缺点是,数据的读取和解析更加复杂。从一个字符集转换为另一个字符集可能会变得非常困难,非常快。

这就是 iconv 命令的用武之地。

如何使用 iconv 命令

iconv 命令在命令行选项方面所缺乏的,它远远弥补了它支持的字符编码数量。它列出了 1100 多种不同的编码,但许多是同一事物的别名。我们可以使用 -l(列表)选项列出所有支持的编码。

iconv -l
iconv -l 命令的输出,列出了 iconv 知道的所有字符编码

要使用 iconv,您需要指定源文件和输出文件,以及要转换的编码和要转换为的编码。如果不指定文件名,iconv 将使用 STDIN 和 STDOUT,从命令行获取其输入并将其输出写入终端窗口。您可以将输入通过管道传输到 iconv,也可以将其输出重定向到文件。

我们将使用带有 STDIN 的 iconv 来说明一些要点。我们需要指定输入文本的编码,因此我们将使用 locale 命令来发现它是什么。

locale
在运行为美国配置的 Ubuntu 的计算机上的区域设置命令的输出

第一行说我们使用美国英语和 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
iconv 命令因错误而停止

这在第一个障碍上失败了。US-ASCII 中没有“à”的等效字符,因此放弃了转换。iconv 使用零偏移计数,因此我们被告知问题发生在位置 6。如果我们添加 -c(继续)选项 iconv 将丢弃不可转换的字符并继续处理输入的其余部分。

echo plain àccented non-English ß Foreign currency € | iconv -f UTF-8 -t US-ASCII
使用 -c 选项使 iconv 忽略错误并继续处理

该命令现在运行完成,但输出中缺少字符。我们可以使iconv通过替换相似的字符或其他表示来提供不可转换字符的近似值。如果它无法做到这一点,它会插入一个问号“?”,这样你可以很容易地看到一个字符没有被转换。

此过程称为音译,要调用它,请将字符串“//TRANSLIT”附加到目标编码中。

echo plain àccented non-English ß Foreign currency € | iconv -f UTF-8 -t US-ASCII//TRANSLIT
告诉iconv使用音译用紧密的替代品替换缺失的字符

现在我们得到了一个完整的输出文本,用“a”代替“à”,“ss”代替“ß”,用“EUR”代替“€”货币符号。

将 iconv 与文件一起使用

将 iconv 与文件一起使用与在命令行上使用它非常相似。要找出源文件的编码类型,我们可以使用 file 命令。

file -i input.txt
使用 file 命令发现文本文件的字符编码

我们的输入文件采用 UTF-16LE 编码。这是一个 16 位小端序编码。它看起来像这样:

less input.txt
编码为 UTF-16LE 的文本文件的内容

如果您眯着眼睛阅读白色字符,则可以挑选出实际的文本字符串。许多软件会错误地将这样的文件视为二进制文件,因此我们会将其转换为 UTF-8。

我们使用 -f(from)选项来指定输入文件的编码,并使用 -t (to) 选项告诉 iconv 我们希望以 UTF-8 格式输出。我们需要使用 -o(输出)选项来命名输出文件。我们不使用选项来命名输入文件——我们只是告诉 iconv 它叫什么。

iconv -f UTF-16LE -t UTF-8//TRANSLIT input.txt -o output.txt
使用 iconv 将文本文件转换为新字符编码

我们的输出文件如下所示:

less output.txt
转换后的文本文件的内容

在需要时供电

您可能不经常使用 iconv,但当您需要它时,它可以节省您的培根。

未经允许不得转载:表盘吧 » 如何在 Linux 上使用 iconv 命令