文件结尾没有换行符

当做一个git diff说: “在文件结尾没有换行符”

好的,文件结尾没有换行符。 有什么大不了的?

信息的意义是什么?它试图告诉我们什么?

这表示你没有换行符(通常是'\n' ,CR或CRLF)在文件末尾。

也就是说,简单地说,文件中的最后一个字节(如果你在Windows上是字节的话)不是换行符。

显示消息是因为否则无法区分在最后有换行符的文件和不是的文件之间的区别。 差异必须输出一个换行符,否则结果将很难阅读或自动处理。

请注意,如果文件格式允许,总是将换行符作为最后一个字符,这是一种很好的风格。 此外,例如,对于C和C ++头文件,这是语言标准所要求的。

这不仅仅是糟糕的风格,在文件上使用其他工具时可能会导致意外的行为。

这里是test.txt

 first line second line 

最后一行没有换行符。 让我们看看文件中有多less行:

 $ wc -l test.txt 1 test.txt 

也许这就是你想要的,但在大多数情况下,你可能会期望文件中有两行。

另外,如果你想合并文件,它可能不会像你所期望的那样:

 $ cat test.txt test.txt first line second linefirst line second line 

最后,如果你要添加一个新行,它会使你的差异略微更嘈杂。 如果您添加了第三行,则会显示第二行的编辑以及新的添加。

它只是表示文件的末尾没有换行符。 这不是一场灾难,它只是一个消息,使得在命令行中查看diff时没有一个更清晰。

如果在现有文件的最后没有换行符的末尾添加一个新的行,那么差异将显示旧的最后一行也被修改,当它在概念上不是。

至less有一个很好的理由在最后添加换行符。

核心问题是你定义的行和是否在线字符序列是否是行的一部分。 基于UNIX的编辑器(如VIM)或工具(如Git)使用EOL字符序列作为行终止符,因此它是行的一部分。 这与在C和Pascal中使用分号(;)类似。 在C中,分号终止语句,在Pascal中分隔它们。

唯一的原因是Unix历史上有一个以换行符结尾的所有可读文本文件的约定。 当时,这避免了在显示或join文本文件时的额外处理,并且避免了将文本文件与包含其他types数据(例如不可读的原始二进制数据)的文件不同地处理。

由于这个惯例,那个时代的许多工具都期望结束换行,包括文本编辑器,差异工具和其他文本处理工具。 Mac OS X是build立在BSD Unix上的,并且Linux被开发为与Unix兼容的,所以两个操作系统都inheritance了相同的约定,行为和工具。

Windows并没有被开发成与Unix兼容,所以它没有相同的约定,大多数Windows软件将处理得很好,没有结尾的换行符。

但是,由于Git是首先为Linux开发的,许多开源软件是build立在Unix兼容系统(如Linux,Mac OS X,FreeBSD等)上的,所以大多数开源社区及其工具(包括编程语言)仍在继续遵循这些惯例。

有一些技术上的理由在1971年是有道理的,但在这个时代,它主要是约定和保持与现有工具的兼容性。

这实际上确实造成了一个问题,因为行结束自动修改脏文件而不做任何更改。 看到这个职位的决议。

用CRLF代替LF

您的原始文件可能没有换行符。

但是,一些像gedit这样的编辑器在linux里默默地在文件末尾添加了新行。 使用这种编辑器时,你不能摆脱这个信息。

我试图解决这个问题是用Visual Studio代码编辑器打开文件

这个编辑器清楚地显示了最后一行,你可以根据需要删除这一行。

对于它的价值,我在Mac上创build了IntelliJ项目时遇到了这个问题,然后将项目移到了我的Windows机器上。 我不得不手动打开每个文件并更改IntelliJ窗口右下方的编码设置。 如果有谁读这个问题,可能不会发生,但可以节省我几个小时的工作…

源文件通常由工具(C,C ++:头文件,Javascript:捆绑器)连接。 如果你忽略换行符,你可以引入讨厌的错误(一个源的最后一行与下一个源文件的第一行连接)。 希望所有的源代码concat工具在那里在连接的文件之间插入一个换行符,但似乎并不总是如此。

问题的症结是 – 在大多数语言中,换行符具有语义意义,文件结束符不是换行符的语言定义的替代。 所以你应该用一个换行符来终止每一个语句/expression式,包括最后一个。