将 ^M(Windows)换行符转换为普通换行符

521

Vim在每行结尾都显示^M

如何在Vim中将其替换为正常的换行符?


1
可能是在vim中将DOS行结尾转换为Linux行结尾的重复问题。 - cfi
3
请将解决方案更改为fileformat change,因为这是最干净的解决方案。 - erikbstack
2
我知道这个问题是关于vim的,但其他一些谷歌搜索也会跳转到这个帖子。因此,如果您在系统上安装了Eclipse,您可以通过几次点击将单个文件或完整文件夹树的行分隔符进行转换:https://dev59.com/P2445IYBdhLWcg3wLXIK#7019737 - Teddy
我喜欢你把普通的换行称为“normal”——与那些^M换行形成对比 :-) - DerMike
@DerMike 我猜所有那些花哨的标准互联网协议都是不正常的? - 0xC0000022L
38个回答

616

命令

:%s/<Ctrl-V><Ctrl-M>/\r/g

<Ctrl-V><Ctrl-M>表示输入Ctrl+V然后输入Ctrl+M

说明

:%s

substitute,%=所有行

<Ctrl-V><Ctrl-M>

^M字符(Ctrl-V是Vim写入Ctrl ^字符的一种方式,Ctrl-M在正则表达式后面写入M,导致^M成为特殊字符)

/\r/

有换行符 (\r)

g

全局执行(不仅在行中的第一次出现)。


21
它移除了^M字符,但没有插入回车符。 - sdot257
14
你需要按下组合键 Ctrl-V/Ctrl-M,而不是将其作为完全一致的文本输入。 - LeopardSkinPillBoxHat
33
如果你的文本中有一个 ^M 紧随其后出现在一个新行上,正确的做法是保留新行但移除 ^M。而进行以下另一种替换会让你的文件间距变为双倍。 - dlamblin
12
如果您仍然缺少回车符(即^M已被删除,但所有内容都在一行上换行),请执行以下操作::%s/<Ctrl-V><Ctrl-M>/\r/g(其中 \r 用换行符替换^M)。 - William Turrell
9
如果你在Windows上运行Vim,那么你需要使用<Ctrl-Q>代替<Ctrl-V>。 - GrandAdmiral
显示剩余18条评论

427

在Linux和Mac OS上,以下操作可行:

:%s/^V^M/^V^M/g

其中^V^M表示按下Ctrl+V,然后按下Ctrl+M

注意:在Windows上,您可能想使用^Q代替^V,因为默认情况下^V被映射为粘贴文本。


3
为什么这个被踩了?它可以在文件因为行末错误而被压缩成一行的情况下正常工作。 - Paul Tomblin
2
@jumpnett,你打错了。 冒号,然后百分号,然后s,然后正斜杠,然后控制v,然后控制m,然后正斜杠,然后控制v,然后控制m,然后正斜杠,然后g,然后回车。 - Paul Tomblin
7
这是针对另一个问题的解决方案,当您的文件中没有新行时,这种情况更为常见。FYI,^M可以通过\ r匹配。 - dlamblin
12
这是一个非常神秘的命令,但在我的Mac上它有效。 - Eric Walker
7
我发现在 MacVim 上,等效的 %s/\r/\r/g 命令对于一个只显示行末 ^M 的文件(按照 MacVim 的说法,就是一行很长的文件)能够很好地工作。显然,在这个命令的模式部分和替换部分中,\r 的含义是不同的。 - RichVel
显示剩余21条评论

194

vim 中,查看文件格式 - DOS 或 Unix:

:set filetype=unix

:set fileformat=unix

该文件将不包含回车符 (CR, ^M) 字符写回。


3
使用命令:set fileformat=unix。对于大多数配置来说,filetype 只会改变所使用的语法类型。 - derGral
6
这解决了我遇到的 bug...Vim 开始将我的 UNIX 格式文件误认为是 Windows 格式,新更改的行在 git 差异中显示出 ^M。 - Thomas Hunter II
我发现一个小问题:如果 Git 在后台更新文件(由于检出),而您已将其设置为与 Vim 打开文件时猜测的设置不同的东西,则在重新加载缓冲区时,Vim 似乎不会重新转换。你最终会得到一堆多余的字符。然后,您可以使用上面的 %s/^V^M/.../g 方法之一。哪个取决于您正在转换的确切格式。 - Leo
1
太好了!因为文件格式是DOS,将其设置为Unix即可,没问题。 - zhaozhi
4
顺便提一下,这也适用于 vi,你可以像使用 ft 作为 filetype 的快捷方式一样,使用 set ff=unix 来快速设置文件格式。 - Posva
显示剩余3条评论

155

1
在Windows7上使用Vim7.4。 - schuess
30
输入 :e ++ff=dos 然后输入 :set ff=unix 将会把文本的换行符转换成合理的格式。 - Mateen Ulhaq
解决方案的回答对我没有用,只有 @MateenUlhaq 的命令帮了我。 - Edenshaw
哎呀,如果只有LF行结束符被认为是“健全的”,并且它被认为是某种二分法,那么我怀疑整个互联网协议都必须被视为“疯狂的”?!...就个人而言,我认为“Unix”方式与“DOS”(和互联网协议)方式都不太合理。 - 0xC0000022L

125

我使用BBEdit创建的文件在MacVim中显示了一堆^M换行符,而不是正常的换行符。以下字符串替换解决了这个问题:

:%s/\r/\r/g

这很有趣,因为我用同一字符替换了换行符,但我想 Vim 只需要获取一个新的 \r 才能正确显示。我很想知道这背后的原理。


1
搜索功能往往倾向于接受更广泛的规则来识别行尾序列。但是,当\r被写入数据时,它具有特定的含义。 - gbarry
这对我在Windows gVim中起作用,可以解决一个没有换行符的文件,只有很多^M的问题。 - flash
4
在这个页面提供的所有解决方案中,这是唯一一个让我成功从 CSV 文件中移除 ^M 的方法。使用 MacVim。 - B6431
+1 对我也有效,我是使用Mobaterm从Windows SSH到Ubuntu Trusty的。 - Carl
所以,尽管指定了\r作为替换字符,但似乎这个操作将所有的\r字符都替换成了\n。我并不抱怨,因为这正是我想要的结果,只是有点奇怪。 - donut
这个答案解释了为什么搜索和替换模式是相同的。我原本认为这没有影响,但在每个上下文中它们被不同地解释 - 我还没有看到过这方面的提及。简短的答案似乎是“\n已经被占用”。 - dcc310

35

首先,使用 :set ff? 命令来确定文件的格式。

我猜它可能是 unix 格式,这意味着你的文件使用 fileformat=dos 创建,在行尾添加了 "^M^J",但是在读取时使用的是 fileformat=unix 格式,只删除了行尾的 "^J",而 "^M" 仍然保留。

只需在 Vim 命令行中输入 :e ++ff=dos,即可将文件格式从 unix 转换为 dos。这应该可以解决问题。如果不行,:%s/\r//g 可以帮助你解决问题。


3
我必须执行两个操作。首先输入 :e ++ff=dos,然后输入 :set ff=unix 并保存文件,命令为 :w - Max

29

为了匹配^M字符,我必须可视化地选择它,然后使用操作系统的复制到剪贴板命令来检索它。在尝试替换命令之前,您可以通过搜索该字符来测试它。

/^M

应该选择第一个不良行。

:%s/^M/\r/g

将所有不正确的^M替换为回车符。

这是在基于gvim 7的MacVim中的函数。

编辑:

在我的Windows 10机器上再次遇到此问题,该机器安装了Ubuntu for Windows,我认为这会导致vim文件格式出现问题。在这种情况下,将ff更改为unix、mac或dos除了将^M更改为^J并再次变回去之外,并没有起到任何作用。

解决方案如下:

:%s/\r$/ /g
:%s/ $//g
我采用这种方式的原因是我想确保不对文件造成破坏。我可以使用:%s/\r$//g命令,但那样会将回车符直接删除,并可能导致意外的结果。相反,我们将单个CR字符(这里是^M字符)转换为空格,然后删除所有行末空格(这对我来说是一个理想的结果)。
抱歉重提一个早已得到解答的老问题,但似乎有些混淆,我想帮助澄清一些问题,因为这在谷歌搜索中排名很高。

1
按下ctrl-v ctrl-m可以插入字符,同样也可以生效。但是\r才是插入正确换行符的方式。 - Metagrapher
1
这是正确的答案。如上所述,使用<ctrl-v><ctrl-m>将字面^M插入命令中。 - carlosayam
1
我同意,尽管我确信如果那时候对我起作用,我就不会发帖了。;) - Metagrapher

24

上述方法都不适用于我,所以我尝试了这个,它起作用了:

键入:%s/

按下CTRL-VCTRL-M

键入//g

按下Enter

因此,在Vim中整体命令应该看起来像:%s/^M//g

这是做什么的::%s(查找和替换)/^M/(那个符号)/(没有字符)g(全局)。


直接命中要害!!可在 Mac 上运行。 - shamail
不错的回答。只是要去掉 ^M,而不是用换行符替换它们(vim linux,ff=dos)。这取决于你使用的哪个操作系统 [mac,windows,linux] 以及当前设置的文件格式(请使用 :set ff? 查看)。你是在 Mac 上吗? - RGD2

18

使用Ctrl+VM获取^M,请注意。

s/^M//g

17

在不需要使用Ctrl键的情况下: :%s/\r$//


1
这也是我做事的方式。我只是经常忘记命令。 - pixel 67
这是推荐的去除这些结尾的方法。 - Metagrapher
这对我的情况也完美地起作用了。 - Enis Arik
Vim 8.1 给我返回 E486: Pattern not found: \r$ - RGD2
这是最佳解决方案,适用于任何操作系统,并且无需将缓冲区与文件关联。 - adamency

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接