Vim文本编码之坑
#20220503更新#
今天又遇到一个问题,即常见的“cat显示正常,vi显示异常”的问题。
有这样一个文件,它的编码是UTF-16(DOS),在windows下用UltraEdit打开能正常显示,提示编码是UTF-16(DOS)。
但是在服务器(centos7系统)用vi打开便是一串乱码了,但说乱也不是很乱,因为夹杂着正常字符的,能隐约看到部分内容,提示内容是这样:
解决方法:根据UltraEdit的提示,知道编码的格式为UTF16le,使用utf16le格式打开文件: vim xx.txt -c "e ++enc=utf16le"
于是把vimrc文件的set fenc(set fileencodings)改了一下,将utf-16的优先级调到前面,文件能正常显示了。
相关vimrc设置:
set encoding=utf-8
set fileencodings=ucs-bom,utf-8,utf-16le,default,latin1,gb2312,cp936,gbk,gb18030
注:其中ucs-bom用于检查文件开头部分的Unicode BOM(Byte Order Mark, 字节序标志),它应当放在"utf-8"或者其他Unicode编码之前,从而可以正常的工作。latin1(ISO-8859-1)为单字节编码。保险起见,修改vimrc文件最好先备份,以防出现乱码错误。
注,据本人经验,utf16-le和utf8的格式类似,vi打开文件时,一般会分不清他们,vi通常会将他们之间优先级较高的作为打开的编码格式。鉴于文本文件的出现UTF-8编码格式的概率要大于utf-16le,为保证大多数情况下的成功率,还是将utf-8的优先级放在utf-16le之前。而对于utf16le,则建议打开的时候显式的指定文件格式打开 vi coding_test.txt -c "e ++enc=utf16le"
#10月10日更新#
今天在windows下用visual studio打开多个fortran文件,均出现了之前提到的“Some bytes have been replaced with...”错误,这就比较尴尬了。最终发现,是因为将windows系统的默认编码设置成了UTF-8的原因。最后改回原来的默认设置,把那个“支持UTF-8编码(beta)”选项关闭之后,就没有出现乱码了。
#10月9日更新#
今天在Linux 上用vim 打开一个文件,vim将其识别成gb18030编码,能正常显示中文,然后进行了修改,保存。之后在windows上用visual studio 打开,提示了之前提到的“Some bytes have been replaced with...”错误,中文无法解决。
解铃还须系铃人,最后是在vim中打开这个文件,set fileencoding=utf-8,将文件的编码格式设置成UTF-8,然后保存。之后再在windows上用visual studio打开,就正常了!
-----------------------------------------------------------------------------------------------------------------------------------------
工作原因,需要在windows和linux上同时对代码进行编辑。有时候会出现一个诡异的现象,在linux的vim显示正常的文件,在windows系统中用visual studio打开时提示
File Load Some bytes have been replaced with the Unicode substitution character while loading file xxx.f90 with Chinese Simplified (GB2312) encoding. Saving the file will not preserve the original file contents.
打开的文件出现的是一堆乱码。 这究竟是怎么造成的?
从字面上看,是这个文件原本是用GB2312进行编码的,但是文件中的一部分是用Unicode编码的。
问题就在于windows和Linux 下的vim之间的默认的文本编码的差异。
在Windows里,默认保存的文本文件,中文的编码格式是GBK编码(cp936)。
而在Linux系统中,当用vim打开windows保存的文本文件时,会先尝试用默认的编码格式(UTF-8)去转换,如果出现转换错误,再尝试用vim配置文件中列出的其它编码格式读取。
这个vim配置文件是vimrc,一般位于/usr/share/vim/vimrc。在这个配置文件中,通过设置fileencodings的值,来告诉vim编辑器依次尝试用这些编码格式打开文件。
设想出现如下的情况:在windows下创建一个文本文件,以windows默认格式(cp936)保存。但是,在linux系统中用vi打开这个文件时,由于某种原因,vi错误地将其识别成了UTF-8编码。这时候再对文件进行改动,那么改动部分就会以UTF-8的编码格式写入。之后再在windows下打开这个文件,就会出现乱码的错误。
另外,如果用vim打开文件时提示:"xxxx.txt" [第 xx 行无效字符][dos] xxxxL, xxxxC ,则意味着出现了转换错误。
造成转换错误意味着文件的文本编码不正确。这里的“文本编码不正确”并不一定意味着所有的编码不正确,因为可能出现一个文件用两种编码保存的情况(可能在文件的这一行用的UTF-8对文本进行编码,在这个文件的下一行用GBK编码文本)。可能用vim打开文件时候,一部分文本能正常显示——这部分文本的编码和vim当前的编码一致,但另一部分文本不能正常显示,这时候尝试切换使用不同格式的编码打开文件,有可能使得这部分文本正常显示(原来能正常显示的文本可能因为切换了编码不能正常显示)。
比如以gbk编码打开文件 vi coding_test.f90 -c "e ++enc=gbk"
在vi中查看文件的编码 set fileencoding
关于中文编码
常见的中文编码有GB2312, GBK, GB13030等。这些带GB*前缀的,是中国定的。其中GB2312历史最早,1980年,支持的汉字字符也最少;GBK 1.0版本是1995年推出的;到了2000年GB18030推出,这一版本除了汉字外,还加入藏、蒙、维等字体
而国际上采用的是UTF编码也支持中文,但是windows下还是默认用的GBK编码。
参考
常见字符编码扫盲(UTF,Unicode, GB2312) - 四-儿 - 博客园 https://www.cnblogs.com/sier/archive/2011/10/02/5676457.html
在Vim中查看文件编码 - 浮沉一梦 - 博客园 https://www.cnblogs.com/jjzd/p/7380487.html
Vim 编辑器底端 [noeol], [dos] 的含义_王佳伟的博客-CSDN博客https://blog.csdn.net/strongwangjiawei/article/details/8236703
不同平台文件格式:dos、unix、mac | 程序员技术之旅 https://www.zhangbj.com/p/370.html
----------------------------20220428----------------------------------
附录 关于Vim的一些选项设置
fileencoding选项('fileencoding' 'fenc')
默认值: 空
设置缓冲区文件中的字符编码。
当'fileencoding'与'encoding'不同时,将在写文件时候完成转换。
当'fileencoding'是空时,将会使用'encoding‘的值,此时在读写文件时候不会发生转换。
当'encoding'和'fileencoding’均为unicode编码,且'fileencoding'不是utf-8时,转换同样会发生。这是因为Unicode内部通常是作为utf-8存储的。
警告:转换可能会导致信息的丢失!当'encoding'是'utf-8'或者其他Unicode编码时,转换最有可能以反向转换生成相同文本的方式发生。当'encoding'不是'utf-8'时,会丢失一些字节!
参见'encoding'查看可能的值。此外,还可以指定转换器可以处理的值,参见bypte-conversion。
当读取文件’fileencoding'将会从'fileencodings'中设置。为了读取一个对于'fileencoding'设定不起作用的特定编码的文件,需要使用++enc参数。一个例外:当'fileencodings'为空时,使用’fileencoding'的值。对于一个新的文件,使用'fileencoding‘作为全局值。
在这里,加入“8bit-”和“2byte-”前缀没有意义,它们被忽略了。当设置了这个选项,值将会转换成小写,所以你也可以用大写字母的值设置。 '_'字符串用'-‘替换。如果从'encoding'列表中识别出一个名称,它将被标准名称替换。例如,“ISO08859”变为“iso-8859-2”。
当设置了这个选项,在开始编辑文件之后'modified'选项将被被设置,因为当写文件时文件将会改变。
记住从模式行改变'fenc‘将会在文本被读取之后发生,所以当文件被写入时候会应用这些选项。如果你在模式行设置了’fenc',你需要设置‘nomodified'以避免无法使用“:q”的情况。
当'modifiable‘关闭时,这个选项不能被改变。
'fe' 注意:在6.0版本之前,这个选项指定了整个Vim的编码,这是个错误。现在使用'encoding'代替了。以前的简称是'fe’将不再被使用。
fileencodings选项('fileencodings' 'fencs')
默认值:“ucs-bom";当'encoding'设置为Unicode编码时,默认是”ucs-bom,utf-8,default,latin1“)
{仅当使用 +multi_byte特性编译时候可用}{不是在Vi中}
这是在对一个已有文件进行编辑时,考虑的一个字符串编码列表。当读取一个文件时,Vim先尝试列表中的第一个字符串编码。如果检测到错误,就尝试接下来一个。当检测到编码起作用,将会把这个值设置到'fileencoding‘变量中。如果全部失败'fileencoding'将会设置为空值,这将意味着将会使用'encoding'的值
警告:转换将会导致信息的丢失!当'encoding'是"utf-8"(或者一个其他的Unicode编码)时,转换最有可能以反向转换生成相同文本的方式发生。当'encoding'不是"utf-8"时,会丢失一些非-ASCII字符!可以使用++bad参数去指定如何处理这些不能被转换的参数。
++bad 这个参数指定了不能被转换的字符以及非法字符事后的处理方式。可以有以下三种值:
++bad=X 对于每个坏字符用一个单字节的字符替换
++bad=keep 保持原来的坏字符,不要转换。注意这将会导致在你的文本中出现非法字节!
++bad=drop 移除坏字符。
默认的比如"++bad=?“: 用每个坏字符用问号字符串替换。在一些情况下一个倒问号将会被使用(0xBF)。
注意不是所有的命令都会用到++bad 参数,即使在对这些命令添加了++bad选项了,它们也不会返回一个错误。比如:write。 、
注意,当读取时候,'fileformat‘和'fileencoding’选项将会设置使用到的格式。当没有进行写操作时,下一次的写操作将会使用旧选项。对于'binary'选项也是一样。
对于一个空文件或者一个仅有ASCII字符串的文件,大多数的编码都会起作用,所以将会使用‘fileencodings’列表的(除了"ucs-bom"以外)第一个条目。如果你需要其他的编码,使用BufReadPost 自动指令事件来测试你预期的编码是否被使用。比如:
au BufReadPost *if search('\S', 'w') ==0) |
\ set fenc=iso-2022-jp |end if
如果文件没有包含非空字符串,将会把设置'fileencodings'成"iso-2022-jp"。
当使用了++enc参数,‘fileencodings'的值将不会被使用。
注意'fileencodings'不对一个新文件起作用,这时候将会使用'fileencoding'选项。
可以使用以下命令来设置:
:set global fenc=iso-8859-2
这意味着不存在的文件将会得到与空文件不同的编码。
特殊的值”default“可以被用于从环境中编码(这是'encoding‘的默认值)。当'encoding'设置成"utf-8",且你的环境使用的是非latin1编码(比如俄语)时,这非常有用。
当'encoding‘是”utf-8"且文件包含了一个非法的字节序列时,他不被被识别为UTF-8。你可以使用8g8命令去查找非法字节序列。
错误值: |
错误的原因: |
latin1, utf-8 utf-8,ucs-bom,latin1 cp1250,latin1 |
"latin1"将会总是使用 在utf-8文件中BOM不会被识别 "cp1250"将会被使用 |
如果'fileencodings'是空的,'fileencoding'将不会被更改。
对于可能的值,请参见'fileencoding'。
直到下一次文件被读取之前,至二个选项将不会起作用
'fileformat' 'ffs'选项('fileformat' 'ffs')
'fileformat' 'ff' 字符串(MS-DOS, MS-Windows, OS/2 默认的值: "dos",Unix默认值:"unix",Macintosh默认值:"mac")
缓存 {不是在vi中}
这个将会设置当前缓存中的<EOL>,用于从文件中读/写缓存:
dos <CR> <NL>
unix <NL>
mac <CR>
当"dos"被使用,在文件最后的CTRL-Z将会被忽略。参见file-formats和file-read。
对于文件的字符编码,参见'fileencoding'.
当设置了'binary',将忽略'fileformat'的值,文件I/O与设置为"unix"的工作方式类似。当开始编辑一个文件时,'fileformats'不为空且'binary’关闭,这个选项将会自动设置。
当这个选项设置时,在编辑文件之后,'modified‘选项将被设置,因为在写文件时文件将会不同,这个选项不会被改变当’modifiable'关闭时。
为了向前兼容:当这个选项设置为'dos'时,'textmode‘被设置,否则'textmode'将被重置。
'fileformats' 'ffs'选项('fileformats' 'ffs')
'默认值:
Vim+Vi MS-DOS, MS-Windows OS2: "dos, unix",
Vim Unix: "unix,dos",
Vim Mac: "mac, unix, dos",
Vi Cygwin: "unix,dos",
Vi others:""
global
{not in vi}
这给出当开始编辑一个新的缓存和从文件中读取到指定缓存时,行结束符(<EOL>)的格式:
- 当为空时,将用'fileformat'定义的格式。这不是自动设置的。
- 当设置了一个名字,再回在新的缓存被打开时应用格式。'fileformat'将会根据缓存设置。当文件被读进一个已有的缓存中时,不管对于这个缓存'fileformat'设置成什么,都将使用'fileformats'的名称。
- 当超过一个名字存在时,将会在读取文件是进行自动<EOL>检测。当开始编辑文件时,关于<EOL>的检测已经完成;
1. 如果所有的行都以<CR><NL>结尾,且'fileformats'包含了"dos",'fileformat'将设置成"dos"。
2. 如果<NL>被发现,且'fileformats'包含了"unix",'fileformat'将设置成"unix"。注意当一个<NL>被发现前面没有<CR>时,"unix"的优先级在"dos"之前。
3. 如果'fileformat'没有被设置,且如果'fileformats'包括了"mac",'fileformat'将被设置为"mac"。
这意味着"mac"仅在以下情况下被采用:
"unix"不存在或在文件中没有发现<NL>,且"dos"不存在或在文件中没有<CR><NL>。
例外:如果"unix"被选定,但在<NL>之前有<CR>,且在文件的头几行中,<CR>符号的数目比<NL>符号的多,则使用"mac"
4. 如果'fileformat'仍然未设置,将使用'fileformats'中的第一个值。
当从文件中读取到存在的缓存中时,以同样的方式完成,但这种情况就像"fileformat"仅为该文件设置了适当的格式一样,选项没有更改。
当设置了'binary'时,‘fileformats'的值将不会采用。
注意到当Vim开始以空的缓存开始时,这个选项将不会被使用。而是在你的.vimrc文件中设置的'fileformat'
对于具有类似DOS的<EOL>(<CR><NL>)的系统,当读取被":source"的文件和对于vimrc文件时,将会以以下方式进行<EOL>检测:
- 当'fileformats'为空时,没有自动检测。将会使用Dos格式。
- 当'fileformats'设置为一个以上名字是,自动检测将会进行。这是基于文件中第一个<EOL>:如果在它之前有<CR>,将使用Dos格式,否则将使用Unix格式。
同样参见file-formats。
对于向前兼容:当这个选项设置为空字符或者单个格式(没有逗号)时,'textauto'将被重置,否则将会设置'textauto'。
注意:当'compatible'被设置时,这个选项被设置为Vi的默认值,当'compatible‘被重置时,这个选项将会设置成Vim的默认值。
Vim文本编码之坑的更多相关文章
- 转 :Vim文件编码识别与乱码处理
Vim文件编码识别与乱码处理 在 Vim 中,有四个与编码有关的选项,它们是:fileencodings.fileencoding.encoding 和 termencoding.在实际使用中,任 ...
- 编码知识梳理(UTF-8, Unicode, GBK, X509, ANSI, VIM中编码)
编码小结 1 初识编码 所谓编码,是信息从一种形式或格式转换为另一种形式的过程. 字符编码,从自然语言的字符的一个集合(如字母表或音节表),到其他东西的一个集合(如号码或电脉冲)的映射 ANSI:wi ...
- [2015.02.02]文本编码转换专家 v2.6
软件名称:文本编码转换专家最新版本:v2.6操作系统:XP/2003/Win7/Win2008软件介绍:文本编码转换专家,界面简洁易用,功能强大实用.自动识别文件编码,有效转换成目标编码.真正的多线程 ...
- node.js整理 03文件操作-遍历目录和文本编码
遍历目录 递归算法 遍历目录时一般使用递归算法,否则就难以编写出简洁的代码. 递归算法与数学归纳法类似,通过不断缩小问题的规模来解决问题 function factorial(n) { if (n = ...
- mac 文本编辑器 文本编码Unicode utf-8 不适用的问题
在mac上使用默认的文本编辑器打开下载的xx.txt文件,如果文本是gbk的编码可能会出现 文本编码Unicode utf-8 不适用的打开错误,如下图 解决方式: 文本编辑---偏好设置-----打 ...
- Mac下用命令行直接批量转换文本编码到UTF8
由于近期在Mac下写Android程序,下载的一些Demo由于编码问题源码里的汉字出现乱码,文件比较多,所以想批量解决下文件的编码问题. Mac下有以下两种方式可以解决: A. 文件名的编码:Mac的 ...
- vim各种编码设置问题
vim各种编码设置问题 vim中主要有四个编码相关的设置,详细是~/.vimrc中: 下面是我的设置: set fileencodings=gb18030,utf-8,gb2312,gbk: set ...
- 011_如何decode url及图片转为base64文本编码总结
一.咱们经常会遇到浏览器给encode后的url,如何转换成咱们都能识别的url呢?很简单,talk is easy,Please show me your code,如下所示: (1)英文decod ...
- (6.2)vim文本编辑器
vi / vim是Unix / Linux上最常用的文本编辑器而且功能非常强大. vim文本编辑器只有命令,没有菜单.
- Linux系统 vi/vim文本编辑器
Linux系统 vi/vim文本编辑器 (一)Vim/Vi简介 (二)Vim/Vi工作模式 (三)Vim/Vi基本使用 (四)Vim/Vi应用技巧 (一)Vim/Vi简介 Vim/Vi是一个功能强大的 ...
随机推荐
- Corundum:100G NIC学习(二)——仿真
前情提要:搭建corundum仿真环境(一)https://www.cnblogs.com/shroud404/articles/15364812.html 三.Running test 接上文,梳理 ...
- 爬小说_BeautifulSoup解析_easy
title: 爬小说_BeautifulSoup解析_easy author: 杨晓东 permalink: 爬小说_BeautifulSoup解析_easy date: 2021-10-02 11: ...
- Java常见面试题收集
1.final.finalize.finally之间的区别 final关键字用于对属性.方法.类进行修饰,表示属性值不可修改,定义的对象地址不可修改.方法不可被覆盖,类不可被继承. finalize( ...
- MSF设置监听
一.msf需要生成一个payload 需要生成一个paylaod,window下面生成一个exe,注意:权限不够用sudo权限 sudo ./msfvenom -p windows/x64/meter ...
- CSS3图片自适应各种尺寸的屏幕
img { max-width: 100%; height: auto;} 设置最大宽度,高度自适应.
- plugin的原理
plugin插件的原理 扩展webpack, 加入自定义的构建行为 webpack内部的钩子 hooks tap: 可以注册同步钩子和异步钩子 tapAsync: 回调方式注册异步钩子 tapProm ...
- P2016题解
P2016题解 题目描述 Bob要建立一个古城堡,城堡中的路形成一棵无根树.他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能瞭望到所有的路. 注意,某个士兵在一个结点上时,与该结点相连的所有边将 ...
- 实验:两片ESP8266,分别做客户端和服务器,实现双向收发数据
手机做热点: 每片都做STATION
- WPF图片的缩放节省内存
一.前言 正好项目用到要加载大量图片,虽然说可以使用WPF提供的自带的UI虚拟化功能,但是直接加载大量的图片到内存还是会 消耗很多的内存,而且WPF支持UI虚拟化的ListBox等容器的布局是Virt ...
- C# RSA加密解密 签名实现
class RSACryptoItem { public RSACryptoServiceProvider Provider; public List<byte> PubKeyBytes; ...