问题背景

  VIM在打开文件的时候如果遇到两种换行符风格(dos与unix)共存的文件,通常会在行尾显示出烦人的^M。如果^M较少,比较容易定位到哪几行出了问题,但是如果^M较多,就很难搞。下面先给出解法,再来做分析。

解决方案

  • ^M较少,需要定位哪几行包含^M,只需要在vim中输入:
/\r
  • ^M较多,需要定位到哪几行不包含^M,只需要在vim中输入:
/^\(.*\r\)\@!.*

原理解析

  要了解如何定位^M,首先得知道^M是如何产生的。要了解^M的产生原因,首先得了解VIM的fileformat——文件换行符风格。

  • 三种换行符风格

换行符风格目前分了三种风格,分别是:

  • DOS-format:采用\r\n换行,在vim中用"dos"表示,Windows系统默认风格
  • unix-format:采用\n换行,在vim中用"unix"表示,unix派系系统默认风格
  • Mac-format:采用\r换行,在vim中用"mac"表示,Mac系统默认风格

想确定当前文件是被vim判断为哪种文件格式,可以在vim内输入“:set fileformat”,如果是unix风格,会在左下角的命令输入行显示如下:

另外还可以用":set fileformats"查看当前配置的vim支持哪些换行符风格,如果能确定当前文件的格式不在可识别文件格式列表内,可以使用":set fileformats=unix,dos,mac"手动添加可识别格式。

三种风格的历史由来感兴趣的同学可以自行百度,还是挺有意思的。

  • vim是如何判断文件的fileformat的
  • 如果所有行都是以 "\r\n" 也就是<CR><NL>结尾,'fileformat' 会被设置为 "dos"
  • 如果 "fileformats" 包含 "mac" 并且文件不含 "\r" 也就是 <NL> 字符,'fileformat' 会被设置为 "mac"
  • 以上两种情况之外的,会设置为 ‘unix’
  • ^M是如何产生的

因为只有当文件所有行都是以 "\r\n" 结尾,能被识别为 "dos" 格式,所有当文件内 "\r\n" 风格和 "\n" 风格共存的时候,就会被标志为 "unix" 风格,而在unix风格中,只有 "\n" 被识别为换行,多余的 "\r" 就会用^M标识出来,^M其实就是 "\r" 在vim中的字符表述。所以在上文中用 "\r" 作为匹配字符串的时候,会匹配到 ^M,如下图所示

  • 匹配不包含^M的行

匹配包含某个字符串的行非常的简单,但是匹配不包含某个字符串的行,就需要花费一番功夫了。具体可以参考这篇博文:http://blog.sina.com.cn/s/blog_9eccc8e50102wd7h.html。博主也是参考了这篇博文之后,才摸索出了上面的匹配不存在^M的行的写法。

总结

  本次最大的收获是从原理上理解了vim是如何判断文件换行符风格的,在了解了原理之后,才能更清晰的认识到^M产生的原因,并且轻松找到应对方案。另外也掌握了vim里面匹配不存在行的技巧,这是一个非常有用的技巧。

VIM从原理上认识^M问题的更多相关文章

  1. AJAX练习(一):制作可以自动校验的表单(从原理上分析ajax的作用)

    继上文(AJAX(一)AJAX的简介和基础)作为联系. 传统网页在注册时检测用户名是否被占用,传统的校验显然缓慢笨拙. 当ajax出现后,这种体验有了很大的改观,因为在用户填写表单时,签名的表单项已经 ...

  2. 从原理上搞定编码(二)-- Web编码

    周末宅在家里睡完觉就吃饭,吃完饭接着睡觉,这日子过的实在是没劲啊.明明还有计划中的事情没有做, 为什么就是不想去做呢,这样的生活持续下去,必然会成为一个彻头彻尾的loser.上一篇写的 初识编码 ,这 ...

  3. 从原理上理解MySQL的优化建议

    从原理上理解MySQL的优化建议 预备知识 B+树索引 mysql的默认存储引擎InnoDB使用B+树来存储数据的,所以在分析优化建议之前,了解一下B+树索引的基本原理. 上图是一个B+树索引示意图, ...

  4. vim plugin 原理

    vim 个性化设置与功能扩展均通过 script 来实现,这种 script 又叫 plugin.plugin 是 vim 的核心与精髓. 最常用的配置文件 vimrc,也是一种 plugin.换句话 ...

  5. vim安装不上

    前阵子,刚安装Ubuntu时,安装vim的问题,现在些出来分享一下.apt-get install vim正在读取软件包列表... 完成正在分析软件包的依赖关系树正在读取状态信息... 完成有一些软件 ...

  6. 001_从原理上搞定编码-- Base64编码

    开发者对 Base64编码肯定很熟悉,是否对它有很清晰的认识就不一定了.实际 上Base64已经简单到不能再简单了,如果对它的理解还是模棱两可实在不应该.大概介绍一下Base64的相关内容,花几分钟时 ...

  7. 从原理上理解NodeJS的适用场景

    NodeJS是近年来比较火的服务端JS平台,这一方面得益于其在后端处理高并发的卓越性能,另一方面在nodeJS平台上的npm.grunt.express等强大的代码与项目管理应用崛起,几乎重新定义了前 ...

  8. 从原理上搞定编码-- Base64编码

    BASE64是一种编码方式,通常用于把二进制数据编码为可写的字符形式的数据.这是一种可逆的编码方式.编码后的数据是一个字符串,其中包含的字符为:A-Z.a-z.0-9.+./共64个字符:26 + 2 ...

  9. apache和nginx原理上的不同之处

    今天群里提到面试时问到apache和nginx原理有什么不同,一时还真没想起,想到的只是他们的优缺点,便搜索了下.记录学习下.顺便记录下优缺点吧. 原理不同之处: 为什么Nginx的性能要比Apach ...

随机推荐

  1. 解决PLSQL Developer中的乱码问题

    很多朋友在使用PLSQL Developer的时候出现了乱码的问题,我就是其中的一员,后来通过网上的查找以及自己的探索,终于找到了最快,最可靠的解决办法,接下来我将告诉大家如何操作 1.首先在PLSQ ...

  2. swift 跳转到系统设置/网络/推送提醒

    使用App-Prefs做域跳转,代码如下: if let url = URL(string: "App-Prefs:root=NOTIFICATIONS_ID"), UIAppli ...

  3. 【leetcode_easy】530. Minimum Absolute Difference in BST

    problem 530. Minimum Absolute Difference in BST 参考 1. Leetcode_easy_530. Minimum Absolute Difference ...

  4. .Netcore 2.0 Ocelot Api网关教程(8)- 缓存

    Ocelot中使用 CacheManager 来支持缓存,官方文档中强烈建议使用该包作为缓存工具.以下介绍通过使用CacheManager来实现Ocelot缓存. 1.通过Nuget添加 Ocelot ...

  5. Linux进程批量管理工具

    在使用docker容器时,可以有单机的docker-compose批量编排工具,甚至还有集群的k8s之类编排工具,那么在Linux系统中同样也有相关的批量管理进程的工具,其中使用最多的应该就是supe ...

  6. hi cnblogs

    hi cnblogs 前言: 作为一个工作好些年的it男,还没正经写过技术博客,真是太羞愧了... 正文: 先扯点儿虚的,无论从事什么行业,最重要的都是自我认知和自我定位.至今,我也有工作了小五年了, ...

  7. python一些小知识点is和编码

    dic = { "name":["alex", "wusir", "taibai"], 'py9':{ "ti ...

  8. Django 实现登录后跳转

    说明 实现网页登录后跳转应该分为两类:即登录成功后跳转和登录失败再次登录成功后跳转.参考网上内容,基本都只实现了第一类.而没有实现第二类. 实现 为了能让登录失败后再次登录成功后还能实现跳转.我这里采 ...

  9. SQLite进阶-19.常用函数

    目录 SQLite常用函数 SQLite常用函数 SQLite 有许多内置函数用于处理字符串或数字数据. 序号 函数 & 描述 1 SQLite COUNT 函数SQLite COUNT 聚集 ...

  10. ObjectMapper 对象和json相互转换

    一.ObjectMapper ObjectMapper类是Jackson库的主要类.它提供一些功能将转换成Java对象匹配JSON结构,反之亦然.它使用JsonParser和JsonGenerator ...