为什么有时候vim会显示^M,有时候又不显示(即使它们存在)?

4
我将尝试从项目的git存储库中删除所有CLRF字符。我正在编写一个命令,递归地通过存储库进行grep以查找实例。但是,有些“命中”在vim中打开时非常明确地显示了^M,而其他一些则不显示这些字符。
然而,在运行以下命令时:
file <filename without visual ^M> 

它说:

blah.java ASCII Java program text, with CRLF line terminators

并且

od -cx <filename without visual ^M>

在返回的文本中有"\r\n"字符。

我想知道为什么vim有时显示它们,有时不显示。

编辑:

我创建了一个测试文本文件,并手动添加了^M(即ctrl V + ctrl M),vim显示了这些字符。然后我运行了:

sed -i '' -e 's/\r//g' controlm.txt

使用vim打开文件后,视觉上的^M符号已经消失了,但od -cx命令仍然显示\r \n符号。不过,接着我运行了以下命令:

sed -i '' -e 's/^M//g' controlm.txt

然后它不仅在vim中移除了可见的^M,我已经确认od -cx显示\r\n现在只是\n。

2个回答

4

这个问题最好在Superuser.com上提问,而不是在这里,因为它涉及到使用vim,而不是编程。但是回答一下:

当打开一个文件时,vim会尝试检测它是MS-DOS/Windows还是unix文件。如果所有行都以\r\n结尾,那么它可能是DOS文件;如果只有一些行是以\r\n结尾的,则vim可能也会认为它是unix文件。如果文件格式设置为DOS,则vim在读取文件时会忽略\r,并在读取文件后的状态行中直接显示[dos]。

在写回文件时,它会以\r\n终止每一行;如果文件格式是unix,则以\n终止每一行。您可以使用以下命令设置模式:

:se fileformat=unix

或者

:se fileformat=dos

在Windows中创建一个名为x.txt的文件,用vim打开它。 然后,输入:se fileformat = unix:w y.txt;之后输入:se fileformat = dos:w z.txt。使用od cx来测试y.txtz.txty.txt将具有\r\n行尾,而z.txt则没有。

当文件中仅有部分,而不是所有行以\r结尾时,例如如果(unix)git向在dos / windows上创建的文件添加了一些标题(没有\r),则文件格式检测将首先看到标题,并假定为unix,在读取时不会从文件的其余部分中删除\r,并将其显示为^M


好的信息,谢谢。我仍然不完全明白为什么如果vim看到它是dos格式(从vim底部的信息栏),并且cli工具“file”说它是一个带有CRLF行终止符的文件,但是当编辑器打开时vim不显示^M。然后在其他文件中,^M被显示出来。编辑哦,我明白了,显示^M的文件有dos / unix行结尾的混合,而那些不显示^M(但od -cx报告)的文件全部都是CRLF结尾,所以VI必须决定以“unix”模式显示并主动显示^M。 - jshort
你写错了顺序。y.txt 文件只有 \n,而 z.txt 文件则有 \r\n - Rick

3

@Guntram Blohm是正确的,但他遗漏了部分答案:选项'fileformats'(简称'ffs')。 如果您

:set ffs=unix
:e dosfile.txt

那么vim将会固执地拒绝接受CRLF行尾,并明确显示所有的^M字符。
:help 'ffs'

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