网赌十大信誉的平台vim字符编码明白和装置验证,让Vim深透送别乱码

3.1 读文件时,VIM探测fileencoding不准确

这很好理解,比如以GBK编码方式存储的文件,VIM把fileencoding探测成了ASCII,则肯定会出现问题。

【解决方法】一是靠VIM自身提高探测水平;二是设置合适的fileencodings变量,把最可能用到的编码方式放到最前面。如果VIM实在是探测不对,那么就只能通过
:set fileencoding=xxx 命令来手动探测了。

4 杜绝乱码的最佳实践

所有编码统统设置为utf-8。这样既能够识别人类所有语言,又避免了各种编码之间转换的性能损失。

convert_encoding.py    基于Python的文本文件转换工具;

3.3 encoding无法正确转换到termencoding

这个问题,与3.2类似。
【解决办法】把termencoding设置为何encoding相同。默认termencoding=”“的情况下,这两者就是相同的。

2.2 vim读、显、存分析

  1. 读文件

VIM打开文件时,并不知道文件的字符编码,所以不得不进行探测。探测是按照一定的优先顺序进行测试。依据的标准就是:fileencodings。VIM逐一测试fileencodings变量指定的字符编码方式,直到找到认为合适的然后把这种字符编码方式设置为fileencoding变量。

然后把文件中的编码转换成encoding指定的编码方式,存入文件缓冲区中。

  1. 显示文件

vim把文件读取完毕并以encoding编码存放到缓冲区内存之后,会根据termencoding指定的终端编码方式,转换成termencoding编码后,写入到终端。此时,终端按照自身的编码属性识别出一个个的字符,调用渲染引擎绘制到屏幕上。

  1. 保存文件

VIM把缓冲区中的encoding编码的字节集合转换成fileencoding编码后写入磁盘,完成文件保存。

可以看出,VIM涉及到的3种字符编码之间的转换:

对文件的操作 编码的转换
fileencoding –> encoding
encoding –> termencoding
encoding –> fileencoding

只要这三种转换都不会出现问题,那么VIM就可以正常工作,不会出现乱码。

然而,并不是所有的字符编码之间都能够无损转换,例如GBK字符编码转换为ASCII编码时,由于ASCII并不能完全包含GBK的字符,所以会出现问题。

 

3.4 终端显示能力欠缺

例如,传统的字符终端,本身不具备显示汉字的能力,虽然它可以识别出UTF-8编码的汉字,但是渲染引擎无法正确绘制,也就显示成了乱码。
【解决办法】尽量还是使用Putty等伪终端软件,避免直接使用字符终端设备;如果实在不能避免,就要避免使用ASCII字符集以外的字符,好好学习英文吧。

【解决办法】

把终端实际的编码方式和VIM的termencoding统一起来。

 

2 VIM读取、显示、保存文本文件过程分析

字符编码

字符编码是代码点的二进制存储格式。还是前面的例子,在ASCII字符集中,A的代码点是65。而这个65究竟是怎么用二进制0和1序列表示呢?这就是字符编码的工作。在ASCII编码中,这个65被存储为01000001,一共占据一个字节(8个二进制位)。

说到这里也许你会觉得,这中区别也没什么啊,这主要是因为在我们的例子中ASCII字符集的代码点只有一种字符编码方式,也就是ASCII字符编码。而这在其他字符集中却不总是这样,例如UNICODE字符集。

UNICODE字符集,规定了全球每一个字符的代码点,例如英文字母A在UNICODE字符集中的代码点是65(哈哈,这个代码点与ASCII是兼容的),然而65的存放格式却有很多方式:例如在UTF-8字符编码规范中被存储为8个二进制位:01000001,而在UCS-16中被存储为16个二进制位:0000000001000001,而在UCS-32中被存储为32个二进制位:00000000000000000000000001000001。

说到这里,就明白了,UNICODE字符集对应有很多不同的字符编码方式:UTF-8,UCS-16,UCS-32等等。

而ASCII字符集只有一种编码方式:ASCII字符编码。

UNICODE字符集的不同编码方式是为了适应不同的环境而被创造出来的,例如UTF-8被用来网络传输,文件存放,UCS-16则被用来作为内存中的存放方式,以利于快速统一计算。

现如今,虽然UNICODE字符集已经获得广泛采用,然而历史遗留的其他字符集仍大量存在。

近年来,字符集的概念很少被提及,字符编码则更多的被使用。

 

1.3 字符编码与显示

对字符进行编码只是完成了存放、处理和传输,要想把字符的形状绘制出来,还要有对应的字体以及渲染手段。

对于GUI程序,操作系统都会提供API来对指定字符进行渲染绘制。对于终端来说,终端有一个字符编码的属性,从而把接收到的二进制字节流按照这个字符编码进行解析,然后调用相应的渲染引擎来对其进行显示,详情请参考我的一篇博文:从调用printf()到显示器上看到字符串。

4.2 终端设置

常用的几种终端软件都设置为utf-8。

:argdo set fenc=utf-8 | update 

1.2 区分字符集(Charset)和字符编码(Char Encoding)

这两个术语有时候不进行区分的使用,但是理解其区别对于理解字符编码至关重要。

  • 代码点(Code Point)
    也就是我们前面说到的,为每一个字符分配一个数字序号。例如在ASCII字符集中,字符A被分配成65号,那就是说A的代码点是65。一种编码规范中,所有的代码点的集合就是字符集。

  • 字符编码
    字符编码是代码点的二进制存储格式。还是前面的例子,在ASCII字符集中,A的代码点是65。而这个65究竟是怎么用二进制0和1序列表示呢?这就是字符编码的工作。在ASCII编码中,这个65被存储为01000001,一共占据一个字节(8个二进制位)。

说到这里也许你会觉得,这中区别也没什么啊,这主要是因为在我们的例子中ASCII字符集的代码点只有一种字符编码方式,也就是ASCII字符编码。而这在其他字符集中却不总是这样,例如UNICODE字符集。

UNICODE字符集,规定了全球每一个字符的代码点,例如英文字母A在UNICODE字符集中的代码点是65(哈哈,这个代码点与ASCII是兼容的),然而65的存放格式却有很多方式:例如在UTF-8字符编码规范中被存储为8个二进制位:01000001,而在UCS-16中被存储为16个二进制位:0000000001000001,而在UCS-32中被存储为32个二进制位:00000000000000000000000001000001。

说到这里,就明白了,UNICODE字符集对应有很多不同的字符编码方式:UTF-8,UCS-16,UCS-32等等。
而ASCII字符集只有一种编码方式:ASCII字符编码。

UNICODE字符集的不同编码方式是为了适应不同的环境而被创造出来的,例如UTF-8被用来网络传输,文件存放,UCS-16则被用来作为内存中的存放方式,以利于快速统一计算。

现如今,虽然UNICODE字符集已经获得广泛采用,然而历史遗留的其他字符集仍大量存在。
近年来,字符集的概念很少被提及,字符编码则更多的被使用。

【解决方法】

把encoding设置成UTF-8,目前为止UTF-8能包含所有字符,所以其他的任何编码方式都可以无损的转换为UTF-8。

    首先,我们先要知道控制Linux OS 的语言环境变量是 $LANG和$LC_ALL,要解决乱码的情况我们只需要把上述的两个变量正确设置即可. 

2.1 VIM涉及到的字符编码

(1) 磁盘文件的字符编码
存放在磁盘上的文本文件,是按照一定的字符编码进行保存的,不同的文件可能使用了不同的字符编码。
这在VIM中被叫做:fileencoding。

(2) VIM缓冲区以及界面的字符编码
VIM运行时,其菜单、标签、以及各个缓冲区统一使用一种字符编码方式。
这在VIM中被叫做:encoding。

(3) 终端使用的字符编码
终端同一时刻只能使用一种字符编码,并按照这种编码从接收到的字节流中识别字符,并显示,终端的字符编码是可以动态调整的。
这在VIM中被叫做:termencoding。

1 字符编码基础知识

字符编码是计算机技术中最基本和最重要的知识之一。如果缺乏相关知识,请自行恶补之。这里仅做最简要的说明。

* termencoding: Vim 所工作的终端 (或者 Windows 的 Console 窗口)
的字符编码方式。如果vim所在的term与vim编码相同,则无需设置。如其不然,你可以用vim的termencoding选项将自动转换成term
的编码.这个选项在 Windows 下对我们常用的 GUI 模式的 gVim 无效,而对
Console 模式的Vim 而言就是 Windows
控制台的代码页,并且通常我们不需要改变它。

1.1 字符编码概述

所谓的字符编码,就是对人类发明的每一个文字进行数字化表示。最经典的ASCII编码就是西方人发明的针对英文字符的编码方法,包括26个英文字母、数字、标点、特殊字符等。问题是,这种编码的范围是0-127,只能对128个字符进行编码。当计算机来到其他国家后发现,除了英语,还有大量的其他语言,而且涵盖的字符也远远多于128个。为此,各个国家开始针对自己的语言进行编码工作,例如中国的GBK,日本的CJK,等等。

这虽然解决了ASCII编码不够用的问题,但是却带来了另外一个更加严重的问题。那就是各个国家的字符编码不统一,导致无法进行统一处理。于是乎,著名的UNICODE出现了,UNICODE编码范围非常大,可以涵盖全球所有语言的字符。

4.1 VIM设置

set encoding=utf-8
set termencoding=utf-8
set fileencodings=utf-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936

如果无特殊要求和限制,磁盘文件也以UTF-8方式存储。

set fileencoding=utf-8

 

3.2 fileencoding编码无法正确转换到encoding编码

例如,文件采用GBK编码,而ecoding使用ASCII,这样大量的汉字字符无法被转换,从而导致乱码。
【解决方法】把encoding设置成UTF-8,目前为止UTF-8能包含所有字符,所以其他的任何编码方式都可以无损的转换为UTF-8。

【解决方法】

一是靠VIM自身提高探测水平;二是设置合适的fileencodings变量,把最可能用到的编码方式放到最前面。如果VIM实在是探测不对,那么就只能通过
:set fileencoding=xxx 命令来手动探测了。

好了,解释完了这一堆容易让新手犯糊涂的参数,我们来看看 Vim
的多字符编码方式支持是如何工作的。

4.2 终端设置

常用的几种终端软件设置。
(1)Putty
网赌十大信誉的平台 1
(2)Mac Terminal
网赌十大信誉的平台 2

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-01/139723.htm

网赌十大信誉的平台 3

3.1 读文件时,VIM探测fileencoding不准确

这很好理解,比如以GBK编码方式存储的文件,VIM把fileencoding探测成了ASCII,则肯定会出现问题。

1.enconv文件名编码转换,比如要将一个GBK编码的文件转换成UTF-8编码,操作如下
enconv -L zh_CN -x UTF-8 filename
enconv -L GB2312 -x UTF-8 test.txt

2.convmv文件名编码转换:
从Linux往windows拷贝文件或者从windows往Linux拷贝文件,有时会出现中文文件名乱码的情况,出现这种问题的原因是因为,windows的文件名中文编码默认为GBK,而Linux中默认文件名编码为UTF8,由于编码不一致,所以导致了文件名乱码的问题,解决这个问题需要对文件名进行转码。在Linux中专门提供了一种工具convmv进行文件名编码的转换,可以将文件名从GBK转换成UTF-8编码,或者从UTF-8转换到GBK。
yum -y install convmv
下面看一下convmv的具体用法:

sudo convmv -f gbk -t utf-8 -r –notest  /home

 常用参数: -r 递归处理子文件夹 --notest 真正进行操作,请注意在默认情况下是不对文件进行真实操作的,而只是试验。 --list 显示所有支持的编码 --unescap 可以做一下转义,比如把%20变成空格 比如我们有一个utf8编码的文件名,转换成GBK编码,命令如下: convmv -f UTF-8 -t GBK --notest utf8编码的文件名 这样转换以后"utf8编码的文件名"会被转换成GBK编码(只是文件名编码的转换,文件内容不会发生变化) 

就是将/home目录下原来文件名是gbk编码方式的全部改为utf-8格式的。这里 -f  后面为原来的编码方式,-t 后面是要更改为的编码方式, -r 表示这个目录下面的所有文件, –notest 表示马上执行,而不是仅仅测试而已。另外这命令好像要root才能执行,因此要加上 sudo。


3.iconv文件内容编码转换:

iconv转换,比如将一个UTF-8 编码的文件转换成GBK编码
iconv -f GBK    -t UTF-8 file1    -o file2
iconv -f GB2312 -t UTF-8 test.txt -o test2.txt  
下载地址:
ftp://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.8.tar.gz 

-f为原来的编码方式,-t 为输出文件的编码方式, -o表示输出文件名,这利用outfile表示,最后跟上要更改编码方式的文件名sourcefile  。
通过这两个工具,中文文件乱码的问题终于解决。

4.unix2dos,dos2unix转换:
使用od -c -t x1 abc.txt 查看文本文件里的特殊字符,DOS/Windows使用/r/n作为行尾符,Unix使用/n作为行尾符: 
unix2dos < unix.txt > dos.txt 将Unix格式的纯文本文件转换成DOS/Windows格式的纯文本文件 
dos2unix < dos.txt > unix.txt 将DOS/Windows格式的纯文本文件转换成Unix格式的纯文本文件 

如果你在openoffice里编辑,是完全兼容的,如果你在vi里 出现/M等符号,可以使用 tr 或 sed工具过滤掉

在Linux下正常换行的文字,到了Windows下后,不再换行。
在Windows下换行时,有两个字符:回车(/r)和换行(/n)。但在Linux下,只有一个换行(/n)
可使用unix2dos和dos2unix命令进行格式的转换:
参数:
-k  保持输出文件和输入文件的日期时间戳不变
-o file   默认模式 . 将file转换,并输出到file
-n  infile outfile 新模式. 转换infile, 并输出到outfile
1.       unix2dos
假设用vi新建一文本文件,输入123456
[root@centos test]# ls -l a.txt
-rw-r--r-- 1 root root 7 Jan  7 21:31 a.txt
[root@centos test]# hexdump -c a.txt
0000000   1   2   3   4   5   6  /n
0000007
[root@centos test]# unix2dos -n a.txt b.txt
unix2dos: converting file a.txt to file b.txt in DOS format ...
[root@centos test]# ls -l
total 8
-rw-r--r-- 1 root root 7 Jan  7 21:31 a.txt
-rw------- 1 root root 8 Jan  7 21:34 b.txt
[root@centos test]# hexdump -c a.txt
0000000   1   2   3   4   5   6  /n
0000007
[root@centos test]# hexdump -c b.txt
0000000   1   2   3   4   5   6  /r  /n
0000008
b.txt是转换后的DOS下的文件
2.       dos2unix
[root@centos test]# dos2unix -n b.txt c.txt
dos2unix: converting file b.txt to file c.txt in UNIX format ...
[root@centos test]# ls -l
total 12
-rw-r--r-- 1 root root 7 Jan  7 21:31 a.txt
-rw------- 1 root root 8 Jan  7 21:34 b.txt
-rw------- 1 root root 7 Jan  7 21:38 c.txt
[root@centos test]# hexdump -c b.txt
0000000   1   2   3   4   5   6  /r  /n
0000008
[root@centos test]# hexdump -c c.txt
0000000   1   2   3   4   5   6  /n
0000007
c.txt是转换后unix下的文本文件

5. enca (如果你的系统中没有安装这个命令,可以用sudo yum install -y enca 安装 )查看文件编码
$ enca filename
filename: Universal transformation format 8 bits; UTF-8
CRLF line terminators
需要说明一点的是,enca对某些GBK编码的文件识别的不是很好,识别时会出现:
Unrecognized encoding

 
5.vim中fileencoding设置文件编码,见文章末尾

od命令
用户通常使用od命令查看特殊格式的文件内容。通过指定该命令的不同选项可以以十进制、八进制、十六进制和ASCII码来显示文件。
语法:od [选项] 文件…
命令中各选项的含义:
- A 指定地址基数,包括:
d 十进制
o 八进制(系统默认值)
x 十六进制
n 不打印位移值
- t 指定数据的显示格式,主要的参数有:
c ASCII字符或反斜杠序列
d 有符号十进制数
f 浮点数
o 八进制(系统默认值为02)
u 无符号十进制数
x 十六进制数
除了选项c以外的其他选项后面都可以跟一个十进制数n,指定每个显示值所包含的字节数。

说明:od命令系统默认的显示方式是八进制,这也是该命令的名称由来(Octal
Dump)。但这不是最有用的显示方式,用ASCII码和十六进制组合的方式能提供更有价值的信息输出。

 od 和 hexdump 显示文件内容或流的八进制、十六进制或其他编码的字节。它们对于访问或可视地检查文件中不能直接显示在终端上的字符很有用。
s-w8每行只用8个字节显示: 
[tim@L gx]$ od -Ad -tax1 -w8 a.txt
0000000   1   2   3   4   5   6  cr  nl
         31  32  33  34  35  36  0d  0a
0000008   a   b   c   d   e   f  cr  nl
         61  62  63  64  65  66  0d  0a
0000016   h   e   l   l   o   ,   w   o
         68  65  6c  6c  6f  2c  77  6f
0000024   r   l   d  cr  nl
         72  6c  64  0d  0a


-j2字符方式输出test内容,跳过前两个字节: 
[tim@L gx]$ od -Ad -tax1 -j2 a.txt
0000002   3   4   5   6  cr  nl   a   b   c   d   e   f  cr  nl   
         33  34  35  36  0d  0a  61  62  63  64  65  66  0d  0a  6
0000018   l   l   o   ,   w   o   r   l   d  cr  nl
         6c  6c  6f  2c  77  6f  72  6c  64  0d  0a
0000029


-N2只显示两个字节,用字符方式显示: 
[tim@L gx]$ od -Ad -tax1 -N2 a.txt
0000000   1   2
         31  32
S

3.3 termencoding与实际的终端字符编码不一致

例如本来字符终端的编码属性为GBK,而termencoding却为UTF-8,那么VIM就会错误的认为终端就是UTF-8编码的,导致向终端输出UTF-8编码的字节流,而终端却按照GBK来识别,当然就会识别成乱码。
【解决办法】把终端实际的编码方式和VIM的termencoding统一起来。

3.5 终端显示能力欠缺

例如,传统的字符终端,本身不具备显示汉字的能力,虽然它可以识别出UTF-8编码的汉字,但是渲染引擎无法正确绘制,也就显示成了乱码。

 

4.1 VIM设置

set encoding=utf-8
set termencoding=utf-8
set fileencodings=utf-8,gbk,latin1

如果无特殊要求和限制,磁盘文件也以UTF-8方式存储。

set fileencoding=utf-8

3.2 fileencoding编码无法正确转换到encoding编码

例如,文件采用GBK编码,而ecoding使用ASCII,这样大量的汉字字符无法被转换,从而导致乱码。

 

3 常见乱码情况分析

代码点(Code Point)

也就是我们前面说到的,为每一个字符分配一个数字序号。例如在ASCII字符集中,字符A被分配成65号,那就是说A的代码点是65。一种编码规范中,所有的代码点的集合就是字符集。

vim 编码设置
和所有的流行文本编辑器一样,Vim 可以很好的编辑各种字符编码的文件,这当然包括UCS-2、UTF-8 等流行的Unicode 编码方式。然而不幸的是,和很多来自 Linux 世界的软件一样,这需要你自己动手设置。
Vim 有四个跟字符编码方式有关的选项,encoding、fileencoding、fileencodings、termencoding (这些选项可能的取值请参考 Vim 在线帮助 :help encoding-names),它们的意义如下:
* encoding: Vim 内部使用的字符编码方式,包括 Vim 的 buffer (缓冲区)、菜单文本、消息文本等。默认是根据你的
locale选择.用户手册上建议只在 .vimrc 中改变它的值,事实上似乎也只有在.vimrc 中改变它的值才有意义。你可以用另外一种编码来编
辑和保存文件,如你的vim的encoding为utf-8,所编辑的文件采用cp936编码,vim会自动将读入的文件转成utf-8(vim的能读懂
的方式),而当你写入文件时,又会自动转回成cp936(文件的保存编码).
* fileencoding: Vim 中当前编辑的文件的字符编码方式,Vim 保存文件时也会将文件保存为这种字符编码方式 (不管是否新文件都如此)。
* fileencodings: Vim自动探测fileencoding的顺序列表,启动时会按照它所列出的字符编码方式逐一探测即将打开的文件的字
符编码方式,并且将 fileencoding 设置为最终探测到的字符编码方式。因此最好将Unicode 编码方式放到这个列表的最前面,将拉丁语系
编码方式 latin1 放到最后面。
* termencoding: Vim 所工作的终端 (或者 Windows 的 Console 窗口) 的字符编码方式。如果vim所在的
term与vim编码相同,则无需设置。如其不然,你可以用vim的termencoding选项将自动转换成term 的编码.这个选项
在 Windows 下对我们常用的 GUI 模式的 gVim 无效,而对 Console 模式的Vim 而言就是 Windows 控制台的代码
页,并且通常我们不需要改变它。

4 杜绝乱码的最佳实践

所有编码统统设置为utf-8。这样既能够识别人类所有语言,又避免了各种编码之间转换的性能损失。

2 VIM读取、显示、保存文本文件过程分析

* fileencodings:
Vim自动探测fileencoding的顺序列表,启动时会按照它所列出的字符编码方式逐一探测即将打开的文件的字符编码方式,并且将
fileencoding 设置为最终探测到的字符编码方式。因此最好将Unicode
编码方式放到这个列表的最前面,将拉丁语系编码方式 latin1 放到最后面。

2.2 vim读、显、存分析

(1)读文件
VIM打开文件时,并不知道文件的字符编码,所以不得不进行探测。探测是按照一定的优先顺序进行测试。依据的标准就是:fileencodings。VIM逐一测试fileencodings变量指定的字符编码方式,直到找到认为合适的然后把这种字符编码方式设置为fileencoding变量。

然后把文件中的编码转换成encoding指定的编码方式,存入文件缓冲区中。
(2)显示文件
vim把文件读取完毕并以encoding编码存放到缓冲区内存之后,会根据termencoding指定的终端编码方式,转换成termencoding编码后,写入到终端。此时,终端按照自身的编码属性识别出一个个的字符,调用渲染引擎绘制到屏幕上。

(3)保存文件
VIM把缓冲区中的encoding编码的字节集合转换成fileencoding编码后写入磁盘,完成文件保存。

可以看出,VIM涉及到的3种字符编码之间的转换:
读:fileencoding—–> encoding
显:encoding ——> termencoding
写:encoding ——-> fileencoding

只要这三种转换都不会出现问题,那么VIM就可以正常工作,不会出现乱码。
然而,并不是所有的字符编码之间都能够无损转换,例如GBK字符编码转换为ASCII编码时,由于ASCII并不能完全包含GBK的字符,所以会出现问题。

【解决办法】

尽量还是使用Putty等伪终端软件,避免直接使用字符终端设备;如果实在不能避免,就要避免使用ASCII字符集以外的字符,好好学习英文吧。

 

1 字符编码基础知识

字符编码是计算机技术中最基本和最重要的知识之一。如果缺乏相关知识,请自行恶补之。这里仅做最简要的说明。

3.4 termencoding与实际的终端字符编码不一致

例如本来字符终端的编码属性为GBK,而termencoding却为UTF-8,那么VIM就会错误的认为终端就是UTF-8编码的,导致向终端输出UTF-8编码的字节流,而终端却按照GBK来识别,当然就会识别成乱码。

文件编码转换

1.3 字符编码与显示

对字符进行编码只是完成了存放、处理和传输,要想把字符的形状绘制出来,还要有对应的字体以及渲染手段。

对于GUI程序,操作系统都会提供API来对指定字符进行渲染绘制。对于终端来说,终端有一个字符编码的属性,从而把接收到的二进制字节流按照这个字符编码进行解析,然后调用相应的渲染引擎来对其进行显示,详情请参考我的一篇博文:从调用printf()到显示器上看到字符串。

 vim对文件的编解码—encoding,fileencoding,fileencodings 

       
vim对于文件的编解码有三个参数,分别是encoding、fileencoding,fileencodings,下面说的应该可以解决绝大多数的问题了。 

        1、支持中文编码的基础 
       
要更好地支持中文编码需要两个特性:+multi_byte和+iconv,可以用|:version|命令检查当前使用的Vim是否支持,否则的话需要重新编译。 

        2、影响中文编码的设置项 
        Vim中有几个选项会影响对多字节编码的支持: 
        encoding(enc):encoding是Vim的内部使用编码,encoding的设置会影响Vim内部的Buffer、消息文字等。在Unix环境下,encoding的默认设置等于locale;Windows环境下会和当前代码页相同。在中文Windows环境下encoding的默认设置是cp936(GBK)。 
        fileencodings(fencs):Vim在打开文件时会根据fileencodings选项来识别文件编码,fileencodings可以同时设置多个编码,Vim会根据设置的顺序来猜测所打开文件的编码。 
        fileencoding(fenc):Vim在保存新建文件时会根据fileencoding的设置编码来保存。如果是打开已有文件,Vim会根据打开文件时所识别的编码来保存,除非在保存时重新设置fileencoding。 
termencodings(tenc):在终端环境下使用Vim时,通过termencoding项来告诉Vim终端所使用的编码。 
        termencodings(tenc):在终端环境下使用Vim时,通过termencoding项来告诉Vim终端所使用的编码。 

        3、Vim中的编码转换 
       
Vim内部使用iconv库进行编码转换,如果这几个选项所设置的编码不一致,Vim就有可能会转换编码。打开已有文件时会从文件编码转换到encoding所设置的编码;保存文件时会从encoding设置的编码转换到fileencoding对应的编码。经常会看到Vim提示[已转换],这是表明Vim内部作了编码转换。终端环境下使用Vim,会从termencoding设置的编码转换到encoding设置的编码。 
        可以用|:help encoding-values|列出Vim支持的所有编码。 

        4、具体应用环境的设置 
        只编辑GBK编码的文件 
        set fileencodings=cp936 
        set fileencoding=cp936 
        set encoding=cp936 

        只编辑UTF-8编码的中文文件 
        set fileencodings=utf-8 
        set fileencoding=utf-8 
        set encoding=cp936 或者 set encoding=utf-8 

        同时支持GBK和UTF-8编码 
        set fileencodings=ucs-bom,utf-8,cp936 
        set fileencoding=utf-8 
        set encoding=cp936 或者 set encoding=utf-8 

       
如果在终端环境下使用Vim,需要设置termencoding和终端所使用的编码一致。例如: 
        set termencoding=cp936 或者 set termencoding=utf-8 

       
Windows记事本编辑UTF-8编码文件时会在文件头上加上三个字节的BOM:EFBBBF。如果fileencodings中设置ucs-bom的目的就是为了能够兼容用记事本编辑的文件,不需要的话可以去掉。Vim在保存UTF-8编码的文件时会去掉BOM。去掉BOM的最大好处是在Unix下能够使用cat
a b>c来正确合并文件,这点经常被忽略。 

 

 

3.3 encoding无法正确转换到termencoding

这个问题,与3.2类似。

  

2.1 VIM涉及到的字符编码

  1. 磁盘文件的字符编码

存放在磁盘上的文本文件,是按照一定的字符编码进行保存的,不同的文件可能使用了不同的字符编码。

这在VIM中被叫做:fileencoding。

  1. VIM缓冲区以及界面的字符编码

VIM运行时,其菜单、标签、以及各个缓冲区统一使用一种字符编码方式。

这在VIM中被叫做:encoding。

  1. 终端使用的字符编码

终端同一时刻只能使用一种字符编码,并按照这种编码从接收到的字节流中识别字符,并显示,终端的字符编码是可以动态调整的。

这在VIM中被叫做:termencoding。

1)设置文件集合,即要对哪些文件进行操作,可以使用通配符,比如我通常是对
C/C++ 源程序进行编码转换

1.1 字符编码概述

所谓的字符编码,就是对人类发明的每一个文字进行数字化表示。最经典的ASCII编码就是西方人发明的针对英文字符的编码方法,包括26个英文字母、数字、标点、特殊字符等。问题是,这种编码的范围是0-127,只能对128个字符进行编码。当计算机来到其他国家后发现,除了英语,还有大量的其他语言,而且涵盖的字符也远远多于128个。为此,各个国家开始针对自己的语言进行编码工作,例如中国的GBK,日本的CJK,等等。

这虽然解决了ASCII编码不够用的问题,但是却带来了另外一个更加严重的问题。那就是各个国家的字符编码不统一,导致无法进行统一处理。于是乎,著名的UNICODE出现了,UNICODE编码范围非常大,可以涵盖全球所有语言的字符。

 

3 常见乱码情况分析

正在开发的WEB系统是部署在RED   HEAD 。 
RH版本信息: 
LSB   Version:         :core-3.1-amd64:core-3.1-ia32:core-3.1-noarch:graphics-3.1-amd64:graphics-3.1-ia32:graphics-3.1-noarch 
Distributor   ID:   RedHatEnterpriseServer 
Description:         Red   Hat   Enterprise   Linux   Server   release   5   (Tikanga) 
Release:                 5 
Codename:               Tikanga 
——————————- 
locale   信息 
LANG=zh_CN.UTF-8 
LC_CTYPE=”zh_CN.UTF-8″ 
LC_NUMERIC=”zh_CN.UTF-8″ 
LC_TIME=”zh_CN.UTF-8″ 
LC_COLLATE=”zh_CN.UTF-8″ 
LC_MONETARY=”zh_CN.UTF-8″ 
LC_MESSAGES=”zh_CN.UTF-8″ 
LC_PAPER=”zh_CN.UTF-8″ 
LC_NAME=”zh_CN.UTF-8″ 
LC_ADDRESS=”zh_CN.UTF-8″ 
LC_TELEPHONE=”zh_CN.UTF-8″ 
LC_MEASUREMENT=”zh_CN.UTF-8″ 
LC_IDENTIFICATION=”zh_CN.UTF-8″ 
LC_ALL= 
——————————— 
因为程序目录有若干文件要读出来显示在页面上,文件名为中文名 
我使用File.list()方法得到了文件名列表,可是显示出来的都是乱码。 
new   String(filename.getBytes(“utf-8″),”GBK”); 
new   String(filename.getBytes(“iso-8859-1″),”GBK”); 
new   String(filename.getBytes(),GBK”); 

【解决办法】

把termencoding设置为何encoding相同。默认termencoding=”“的情况下,这两者就是相同的。

set encoding=utf-8 fileencodings=ucs-bom,utf-8,cp936

1.2 区分字符集(Charset)和字符编码(Char Encoding)

这两个术语有时候不进行区分的使用,但是理解其区别对于理解字符编码至关重要。

 

 

 

使用wc命令來進行文本內容統計:
指令名稱:wc
語法:wc [clw] file
說明:按照不同選項來統計字節數、字數、行數等。具體應用實例請自行 'man wc'來查看。
例子:統計當前目錄下文件的個數,使用命令 ls -l | wc -l
ps:該指令的參數選項比較少,曾有人使用C語言實現了wc的功能,你也可以試試哦!

使用sort命令對文本內容進行排序:
指令名稱:sort
語法:sort [-bcdfimMnr][-o<输出文件>][-t<分隔字符>][+<起始栏位>-<结束栏位>][--help][--verison][文件]
選項解釋:(更多說明請自行man sort)
-n:按照數目排序,number
-r:降序排序
-u:去除重複項


使用uniq命令對文本進行重複列的查看和刪除:
指令名稱:uniq
語法:uniq [選項] file
說明:顯示文本中行的某些特性。
選項解釋:(更多說明請自行 man uniq)
-c:在行首加上該行出現的次數,count的縮寫。
-d:只顯示重複行
-u:顯示不重複的行


使用diff命令對文本進行比較操作:
指令名稱:diff
語法:diff [選項] file1 file2
說明:diff是以逐行的方式,對兩個文件進行異同的操作。
選項解釋:(更多說明請自行 man diff)
-i:忽略大小寫的差別
-b:忽略空格的差別

使用du命令統計目錄或文件佔用磁盤空間大小:
指令名稱:du
語法:du [選項] 目錄或文件
選項解釋:(更多說明請自行 man du)
-k/m/g: 以kb、mb、gb顯示大小
du -S | sort -n 列出佔用空間最大的目錄
-sh:只查看指定的目錄,子目錄不查看

使用cut命令來提取想要的數據:
指令名稱:cut
語法:cut [選項] 文件
用法說明:
-b:截取字節
-c:截取字符
    cut -c1-15 表示截取從第一列到15列的內容
    cut -c1-4,8- 表示截取1到4列的內容,還有從第八列到最後的內容
-f:截取字段
    cut -f1 -d‘:' 表示截取第一列,是以:作為分隔符來截取的
    cut -f1-    -s:表示截取中間的分隔符為Tab鍵分割的文本
ps:截取中文的時候需要注意中文字符是作為2個英文字符組成的。


使用dd命令來測試磁盤速度、創建新文件:
指令名稱:dd
指令說明:從指定位置copy數據到指定輸出位置
應用實例:bs指定每次操作塊的大小,count指定操作的次數
創建2M大小的文件。
# dd if=/dev/zero of=/home/test/2M.txt bs=1024 count=2048
同樣的,測試磁盤讀寫速度
# dd if=/dev/zero of=/home/rwspeed.ret bs=1024 count=1048576
複製備份系統
# dd if=/home/test/my_fiter of=/其他設備 bs=512 count=256
ps:windows平臺上也存在著創建指定大小文件的命令,是 fsutil 。

使用nice命令來調整程序執行的優先級:
指令名稱:nice
指令說明:調整進程的優先級
應用實例:Linux進程的優先級是從 -20 ~ +20 的,數字越小,優先級越高,也就是佔用CPU的時間越多。
普通用戶只能降低程序的優先級,root用戶可以提高/降低進程的優先級。
# nice 查看默認的優先級
# nice ./a.out 默認執行,給a.out增加10個優先級,也就是分配更少的cpu時間。
# nice -n -20 a.out 為a.out執行最高的優先級
Unix/Linux上面的命令很多,這是無數黑客和全世界的程序員們的智慧結晶。
熟練的掌握和使用系統提供的命令,往往會事倍功半。這裡只列出了很少的一部份,
其它的命令可以參考該網站的介紹,或者是找本介紹詳細的書籍來看看。

都不起作用, 
使用 System.getProperty(“file.encoding”) 得出的是”utf-8″ 
另外,使用   ls   命令查看的时候,是乱码,使用   ls   –show-control-chars   命令就能显示中文名(控制台)

Vim 的多字符编码工作方式
1. Vim 启动,根据 .vimrc 中设置的 encoding 的值来设置 buffer、菜单文本、消息文的字符编码方式。
2. 读取需要编辑的文件,根据 fileencodings 中列出的字符编码方式逐一探测该文件编码方式。并设置 fileencoding 为探测到的,看起来是正确的 (注1) 字符编码方式。
3. 对比 fileencoding 和 encoding 的值,若不同则调用 iconv 将文件内容转换为encoding 所描述的字符编码方
式,并且把转换后的内容放到为此文件开辟的 buffer 里,此时我们就可以开始编辑这个文件了。注意,完成这一步动作需要调用外部
的 iconv.dll(注2),你需要保证这个文件存在于 $VIMRUNTIME 或者其他列在 PATH 环境变量中的目录里。

由于中文的字符集编码很多,我自己也不是十分清楚彼此的兼容性如何,所以就尽可能的找了很多种不同的编码都写了上去,大家也可以自己筛选下,总的解决思路就是修改控制环境参数的变量,增加OS所支持的字符集(前提要内核上存在该字符,否则需要编译内核)…

2.X-window(图形界面)的乱码 
vi /etc/sysconfig/i18n 
LANG=”zh_CN.GB18030:zh_CN.GB2312:zh_CN.GBK:zh_CN:en_US.UTF-8:en_US:en:zh:zh_TW:zh_CN.BIG5″ 
LANGUAGE=”zh_CN.GB18030:zh_CN.GB2312:zh_CN.GBK:zh_CN:en_US.UTF-8:en_US:en:zh:zh_TW:zh_CN.BIG5″ 
保存reboot即可… 

这样,就可以让vim自动识别文件编码(可以自动识别UTF-8或者GBK编码的文件),其实就是依照fileencodings提供的编码列表尝试,如果没有找到合适的编码,就用latin-1(ASCII)编码打开

添加 locale, 估计你的系统不支持gbk字符集。
ubuntu下是 vi /var/lib/locales/supported.d/local 
加完后 locale-gen一下, 重新刷新字符集缓存。

  1. Vim 启动,根据 .vimrc 中设置的 encoding 的值来设置
    buffer、菜单文本、消息文的字符编码方式。

  2. 读取需要编辑的文件,根据 fileencodings
    中列出的字符编码方式逐一探测该文件编码方式。并设置 fileencoding
    为探测到的,看起来是正确的 (注1) 字符编码方式。

  3. 对比 fileencoding 和 encoding 的值,若不同则调用 iconv
    将文件内容转换为encoding
    所描述的字符编码方式,并且把转换后的内容放到为此文件开辟的 buffer
    里,此时我们就可以开始编辑这个文件了。注意,完成这一步动作需要调用外部的
    iconv.dll(注2),你需要保证这个文件存在于 $VIMRUNTIME 或者其他列在 PATH
    环境变量中的目录里。

  4. 编辑完成后保存文件时,再次对比 fileencoding 和 encoding
    的值。若不同,再次调用 iconv 将即将保存的 buffer 中的文本转换为
    fileencoding
    所描述的字符编码方式,并保存到指定的文件中。同样,这需要调用
    iconv.dll由于 Unicode 能够包含几乎所有的语言的字符,而且 Unicode 的
    UTF-8 编码方式又是非常具有性价比的编码方式 (空间消耗比 UCS-2
    小),因此建议 encoding 的值设置为utf-8。这么做的另一个理由是 encoding
    设置为 utf-8 时,Vim 自动探测文件的编码方式会更准确
    (或许这个理由才是主要的 ;)。我们在中文 Windows
    里编辑的文件,为了兼顾与其他软件的兼容性,文件编码还是设置为 GB2312/GBK
    比较合适,因此 fileencoding 建议设置为 chinese (chinese 是个别名,在
    Unix 里表示 gb2312,在 Windows 里表示cp936,也就是 GBK 的代码页)。

乱码分两种情况: 
1.终端(纯shell界面)的乱码 
vi /etc/profile 
export LC_ALL=”zh_CN.GB18030:zh_CN.GB2312:zh_CN.GBK:zh_CN:en_US.UTF-8:en_US:en:zh:zh_TW:zh_CN.BIG5″ 
保存退出,reboot系统即可.. 

 

decodeh.py    提供算法和模块来谈测字符的编码;

 

* encoding: Vim 内部使用的字符编码方式,包括 Vim 的 buffer
(缓冲区)、菜单文本、消息文本等。默认是根据你的locale选择.用户手册上建议只在
.vimrc 中改变它的值,事实上似乎也只有在.vimrc
中改变它的值才有意义。你可以用另外一种编码来编辑和保存文件,如你的vim的encoding为utf-8,所编辑的文件采用cp936编码,vim会
自动将读入的文件转成utf-8(vim的能读懂的方式),而当你写入文件时,又会自动转回成cp936(文件的保存编码).

* fileencoding: Vim 中当前编辑的文件的字符编码方式,Vim
保存文件时也会将文件保存为这种字符编码方式 (不管是否新文件都如此)。

* *

vim
编码方式选项(encoding、fileencoding、fileencodings、termencoding介绍)

3.在Vim中查看,转换文件编码

vim中查询修改文件编码格式

set fileencoding
查看现在文本的编码

:set fenc=编码
转换当前文本的编码为指定的编码

:set enc=编码
以指定的编码显示文本,但不保存到文件中。
这里的“编码”常见为gbk utf-8 big5 cp936

:set ff?
查看当前文本的模式类型,一般为dos,unix

:set ff=dos
设置为dos模式

也可以用一下方式转换为unix模式
:%s/^M//g
等同于:set ff=unix 



        5、FAQ 
        为什么在Vim中一次只能删除半个汉字? 
        因为encoding设置错误,把encoding设置为cp936就可以解决此问题。在Unix环境下Vim会根据locale来设置默认的encoding,如果没有正确设置locale并且没有设置encoding就会一次只能删除半个汉字。 
        VIM为什么不能输入繁体字? 
        把euc-cn或者GB2312改为cp936就可以了。euc-cn是GB2312的别名,不支持繁体汉字。cp936是GBK的别名,是GB2312的超集,可以支持繁体汉字。 
        VIM为什么提示不能转换? 
        因为在编译Vim时没有加入iconv选项,重新编译Vim才能解决。 
        如何打开一个GBK编码的文件并另存为UTf-8编码? 
        保存文件时运行命令|:set fileencoding=utf-8|就可以了。 

:set fileencoding ,gb2312不转utf8不能使用egrep 即可显示文件编码格式。 如果你只是想查看其它编码格式的文件或者想解决 用Vim查看文件乱码 的问题,那么你可以在 ~/.vim rc 文件中添加以下内容: set encoding=utf-8 fileencodings=ucs-bom,utf-8,cp936 这样,就可以让vim自动 识别文件编码(可以自动识别UTF-8或者GBK编码的文件),其实就是依照fileencodings提供的编码列表尝试,如果没有找到合适的编码,就用latin-1(ASCII)编码打开。
出现^M(\r)(回车符号),原因是:

輸入 :set ff=unix 後,儲存該文件檔案即可。
vim文件编码转换:在Vim中直接进行转换文件编码,比如将一个文件转换成utf-8格式:set fileencoding=utf-8

 

 

 

:args *.h *.cpp

2)给出要在每个文件上执行的命令,这里是转换编码:

~/.vimrc 文件中添加以下内容:

在 Vim 中,有四个与编码有关的选项,它们是:fileencodings、fileencoding、encoding 和 termencoding。在实际使用中,任何一个选项出现错误,都会导致出现乱码。因此,每一个 Vim 用户都应该明确这四个选项的含义。下面,我们详细介绍一下这四个选项的含义和作用。
1 encoding

encoding 是 Vim 内部使用的字符编码方式。当我们设置了 encoding 之后,Vim 内部所有的 buffer、寄存器、脚本中的字符串等,全都使用这个编码。Vim 在工作的时候,如果编码方式与它的内部编码不一致,它会先把编码转换成内部编码。如果工作用的编码中含有无法转换为内部编码的字符,在这些字符就会丢失。因此,在选择 Vim 的内部编码的时候,一定要使用一种表现能力足够强的编码,以免影响正常工作。

由于 encoding 选项涉及到 Vim 中所有字符的内部表示,因此只能在 Vim 启动的时候设置一次。在 Vim 工作过程中修改encoding 会造成非常多的问题。如果没有特别的理由,请始终将 encoding 设置为 utf-8。为了避免在非 UTF-8 的系统如 Windows 下,菜单和系统提示出现乱码,可同时做这几项设置:
set encoding=utf-8
set langmenu=zh_CN.UTF-8
language message zh_CN.UTF-8
2 termencoding

termencoding 是 Vim 用于屏幕显示的编码,在显示的时候,Vim 会把内部编码转换为屏幕编码,再用于输出。内部编码中含有无法转换为屏幕编码的字符时,该字符会变成问号,但不会影响对它的编辑操作。如果 termencoding 没有设置,则直接使用encoding 不进行转换。

举个例子,当你在 Windows 下通过 telnet 登录 Linux 工作站时,由于 Windows 的 telnet 是 GBK 编码的,而 Linux 下使用 UTF-8 编码,你在 telnet 下的 Vim 中就会乱码。此时有两种消除乱码的方式:一是把 Vim 的 encoding 改为 gbk,另一种方法是保持 encoding 为 utf-8,把 termencoding 改为 gbk,让 Vim 在显示的时候转码。显然,使用前一种方法时,如果遇到编辑的文件中含有 GBK 无法表示的字符时,这些字符就会丢失。但如果使用后一种方法,虽然由于终端所限,这些字符无法显示,但在编辑过程中这些字符是不会丢失的。

对于图形界面下的 GVim,它的显示不依赖 TERM,因此 termencoding 对于它没有意义。在 GTK2 下的 GVim 中,termencoding 永远是 utf-8,并且不能修改。而 Windows 下的 GVim 则忽略 termencoding 的存在。
3 fileencoding

当 Vim 从磁盘上读取文件的时候,会对文件的编码进行探测。如果文件的编码方式和 Vim 的内部编码方式不同,Vim 就会对编码进行转换。转换完毕后,Vim 会将 fileencoding 选项设置为文件的编码。当 Vim 存盘的时候,如果 encoding 和fileencoding 不一样,Vim 就会进行编码转换。因此,通过打开文件后设置 fileencoding,我们可以将文件由一种编码转换为另一种编码。但是,由前面的介绍可以看出,fileencoding 是在打开文件的时候,由 Vim 进行探测后自动设置的。因此,如果出现乱码,我们无法通过在打开文件后重新设置 fileencoding 来纠正乱码。
4 fileencodings

编码的自动识别是通过设置 fileencodings 实现的,注意是复数形式。fileencodings 是一个用逗号分隔的列表,列表中的每一项是一种编码的名称。当我们打开文件的时候,VIM 按顺序使用 fileencodings 中的编码进行尝试解码,如果成功的话,就使用该编码方式进行解码,并将 fileencoding 设置为这个值,如果失败的话,就继续试验下一个编码。

因此,我们在设置 fileencodings 的时候,一定要把要求严格的、当文件不是这个编码的时候更容易出现解码失败的编码方式放在前面,把宽松的编码方式放在后面。

例如,latin1 是一种非常宽松的编码方式,任何一种编码方式得到的文本,用 latin1 进行解码,都不会发生解码失败——当然,解码得到的结果自然也就是理所当然的“乱码”。因此,如果你把 latin1 放到了 fileencodings 的第一位的话,打开任何中文文件都是乱码也就是理所当然的了。

以下是滇狐推荐的一个 fileencodings 设置:
set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,euc-jp,euc-kr,latin1

其中,ucs-bom 是一种非常严格的编码,非该编码的文件几乎没有可能被误判为 ucs-bom,因此放在第一位。

utf-8 也相当严格,除了很短的文件外(例如许多人津津乐道的 GBK 编码的“联通”被误判为 UTF-8 编码的经典错误),现实生活中一般文件是几乎不可能被误判的,因此放在第二位。

接下来是 cp936 和 gb18030,这两种编码相对宽松,如果放前面的话,会出现大量误判,所以就让它们靠后一些。cp936 的编码空间比 gb18030 小,所以把 cp936 放在 gb18030 前面。

至于 big5、euc-jp 和 euc-kr,它们的严格程度和 cp936 差不多,把它们放在后面,在编辑这些编码的文件的时候必然出现大量误判,但这是 Vim 内置编码探测机制没有办法解决的事。由于中国用户很少有机会编辑这些编码的文件,因此我们还是决定把 cp936 和 gb18030 前提以保证这些编码的识别。

最后就是 latin1 了。它是一种极其宽松的编码,以至于我们不得不把它放在最后一位。不过可惜的是,当你碰到一个真的 latin1 编码的文件时,绝大部分情况下,它没有机会 fall-back 到 latin1,往往在前面的编码中就被误判了。不过,正如前面所说的,中国用户没有太多机会接触这样的文件。

如果编码被误判了,解码后的结果就无法被人类识别,于是我们就说,这个文件乱码了。此时,如果你知道这个文件的正确编码的话,可以在打开文件的时候使用 ++enc=encoding 的方式来打开文件,如:

:e ++enc=utf-8 myfile.txt
5 fencview

根据前面的介绍,我们知道,通过 Vim 内置的编码识别机制,识别率是很低的,尤其是对于简体中文 (GBK/GB18030)、繁体中文 (Big5)、日文 (euc-jp) 和韩文 (euc-kr) 之间的识别。而对于普通用户而言,肉眼看出一个文件的编码方式也是很不现实的事情。因此,滇狐强烈推荐水木社区的 mbbill 开发的 fencview 插件。该插件使用词频统计的方式识别编码,正确率非常高。点击这里 下载。

4. 编辑完成后保存文件时,再次对比 fileencoding 和 encoding 的值。若不同,再次调用 iconv 将即将保存
的 buffer 中的文本转换为 fileencoding 所描述的字符编码方式,并保存到指定的文件中。同样,这需要调用 iconv.dll由
于 Unicode 能够包含几乎所有的语言的字符,而且 Unicode 的 UTF-8 编码方式又是非常具有性价比的编码方式 (空间消耗
比 UCS-2 小),因此建议 encoding 的值设置为utf-8。这么做的另一个理由是 encoding 设置为 utf-
8 时,Vim 自动探测文件的编码方式会更准确 (或许这个理由才是主要的  。我们在中文 Windows 里编辑的文件,为了兼顾与其他软件的兼容
性,文件编码还是设置为 GB2312/GBK 比较合适,因此 fileencoding 建议设置为 chinese (chinese 是个别名,
在 Unix 里表示 gb2312,在 Windows 里表示cp936,也就是 GBK 的代码页)。

 

Post Author: admin

发表评论

电子邮件地址不会被公开。 必填项已用*标注