cat输出与vi输出不同

时间:2016-02-03 05:23:27

标签: unix vim utf-8 cat

当我捕捉文件时显示

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

当我进入它时,它显示:

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

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

2 个答案:

答案 0 :(得分:3)

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

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

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

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

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

但看起来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 '...';

答案 1 :(得分:1)

cat愚蠢 - 只是回应你的终端。如果您的终端不了解它接收的字节,您的终端(而不是猫)可能会选择将这些字符呈现为"替换字符U + FFFD" (�),或者字节可能与终端编码中的错误点匹配。如果您的终端编码与文件的编码匹配,那么您将很幸运。

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

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