【问题标题】:cat output different to vi outputcat 输出不同于 vi 输出
【发布时间】:2016-02-03 05:23:27
【问题描述】:

当我 cat 显示文件时

"dest_info_s": "B\u001e�����"

当我 vi 进入它时,它显示:

"dest_info_s": "B\u001eøøïùÄ"

我认为这是由于文件的编码方式和 vi 正在做一些 cat 无法做的转换? 如何删除文件上的编码,使其仅显示为文本? 我想删除编码的原因是因为 sed 在文件上无法正常工作以进行替换,因为它将 sed 命令中的文本与编码文本进行比较并且没有得到匹配。

【问题讨论】:

  • 你需要调整你的终端。它需要 UTF-8,但数据不是 UTF-8(它可能是 ISO 8859-1)。或者你需要修复你的数据。字符有代码 0xF8(两次)、0xEF、0xF9、0xC4 — 其中 0xF8 和 0xF9 在 UTF-8 中无条件无效,另外两个需要连续字节才能成为有效的 UTF-8(0xC4 需要一个连续字节;0xEF 需要两个连续字节)。我不完全确定vim 为何/如何正确编码,但cat 将原始字节发送到您的终端,显示的是您的终端说“我不喜欢那样”。

标签: unix vim utf-8 cat


【解决方案1】:

无论存储在何处或打印在何种显示设备上,所有文本都必须使用一种或另一种编码进行编码。从文本文件中“删除编码”是不可能的。您所能做的就是将文本从其源编码转换为目标编码。一段文本的编码就像能量:你无法创造或摧毁它,你所能做的就是将它从一种形式转换为另一种形式。

打印一段文本时呈现的字素取决于 (1) 文本的编码,(2) 打印文本的程序(具体来说,它是否在将数据传递给显示设备),以及(3)实际负责呈现文本的显示设备的配置和字体支持。在您的情况下,我们谈论的是 (1) 您的文本文件的编码,(2) cat 和 vim,以及 (3) 您的虚拟终端。

cat 实用程序大多不识别文本,并且从不进行任何文本编码转换;它基本上只是将它从输入源接收到的字节复制到它的标准输出。

假设您没有使用非常旧的 vim 版本,它会动态检测文件的编码并在 'fileencoding' 设置中捕获它(注意:对于此检测,它仅尝试在 'fileencodings' 中指定的编码),其内部存储编码使用'encoding'(与我们的目的无关),并在解释键盘输入和向终端打印文本时使用'termencoding'

根据您的示例输出,我猜测您的文本文件是每个字符一个字节的编码,可能是 latin1,并且您的终端配置为使用 UTF-8 编码。这就是 cat 输出将最后 5 个字节呈现为 REPLACEMENT CHARACTER U+FFFD � 的原因。这 5 个字节代表非 ASCII 字符,因此不是有效的 UTF-8。当您看到 U+FFFD 字形时,您的终端会告诉您您发送了无效的 UTF-8。 (注意:有时终端使用 MEDIUM SHADE U+2592 ▒ 而不是 U+FFFD 来表示无效的 UTF-8 字节,有时您会看到显示设备字体不支持的有效 UTF-8 字符呈现不同的字形;请参阅@ 987654327@.)

但是看起来vim正确识别了文件编码,它的终端编码思想也是正确的。因此,当它将文件内容打印到终端时,它会正确地在源编码字节和相应的 UTF-8 表示之间进行转换。因此,5 个非 ASCII 字符正确显示为正确的字素。

如果我上面的推论是正确的,你不需要改变任何设置; cat、vim 和您的终端都运行正常。

如果您希望能够手动将文件内容打印到终端,而不依赖于 vim,您可以使用iconv 程序执行必要的转换。像这样(假设 latin1 是源编码):

iconv -f latin1 -t UTF-8 file.txt;

通常建议始终尝试使用 UTF-8。我不确定为什么您的 sed 命令不起作用(这取决于您未提供的 sed 命令的详细信息),但您可以通过存储文件的 UTF-8 编码版本来使其工作某处,然后在其上运行 sed 命令:

iconv -f latin1 -t UTF-8 file.txt >file-utf8.txt;
sed '...' file-utf8.txt;

或者,您可以使用管道一次性完成:

iconv -f latin1 -t UTF-8 file.txt| sed '...';

【讨论】:

    【解决方案2】:

    cat 是哑巴——它只是回应你终端的响应。如果您的终端不理解它接收的字节,您的终端(不是 cat)可能会选择将这些字符呈现为“REPLACEMENT CHARACTER U+FFFD”(�),或者这些字节可能与终端编码中的错误点匹配。如果您的终端编码与文件的编码匹配,那么您会很幸运。

    虽然它对 cat 没有帮助,但您应该始终确保您的语言环境与您的终端仿真相匹配。这有助于 vi 等工具在屏幕和文件之间进行适当的转换。

    例如,我的终端仿真设置为UTF-8,我的区域设置为en_GB.UTF-8。使用 LANG 环境更改您的语言环境。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-21
      • 1970-01-01
      • 1970-01-01
      • 2011-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多