Vim 为啥要在文件末尾添加新行?

Posted

技术标签:

【中文标题】Vim 为啥要在文件末尾添加新行?【英文标题】:Why would Vim add a new line at the end of a file?Vim 为什么要在文件末尾添加新行? 【发布时间】:2012-12-19 17:23:23 【问题描述】:

我经常使用 Wordpress,有时我会临时更改 Wordpress 核心文件以了解发生了什么,尤其是在调试时。今天我得到了一个小惊喜。当我准备好将我的更改提交到我的 git 存储库时,我注意到 git status 正在将一个 Wordpress 文件标记为未暂存以进行提交。我记得在关闭它之前我已经恢复了我对该文件所做的所有更改,所以我决定使用diff 来查看发生了什么变化。我将项目中的文件与我保存在下载目录中的 Wordpress 副本中的文件进行了比较。事实证明,文件最后不同。 diff 表示原文件末尾缺少换行符:

1724c1724
< 
\ No newline at end of file
---
> 

我什至从未碰过那条线。我在大文件中间某处所做的更改。这让我认为 vim 在文件末尾添加了一个换行符。为什么会这样?

【问题讨论】:

这不是 VIM Disable Automatic Newline At End Of File 的副本。这个问题是在询问原因:“Vim 为什么要这样做?”。 谢谢佩克。正是句子措辞中的小细节使一切变得不同。 【参考方案1】:

添加换行符是 Vim 的默认行为。如果你不需要它,那么使用这个解决方案:VIM Disable Automatic Newline At End Of File

要禁用,请将其添加到您的 .vimrc

set fileformats+=dos

【讨论】:

那里的那个 git 解决方案看起来也很有趣。 谢谢,我不知道这是 Vim 的默认行为。 这对我不起作用。我将fileformats 设置为unix,dos,mac(我在OS X 上),但vim 仍然按照OP 的描述添加EOF 换行符。 在这里不起作用 - linux ubuntu。正如 Max 所说,我必须使用 set noeol binary。【参考方案2】:

您可以将以下行放入您的 .vimrc 中

autocmd FileType php setlocal noeol binary

这应该可以解决问题,但实际上您的方法有些错误。首先php 根本不介意结束,其次如果您不想保存更改,请不要按u 或更糟糕的是手动尝试重新创建文件的状态,但不保存就退出q!。如果您出于某种原因离开了编辑器并保存了,请尝试git checkout &lt;file&gt;

【讨论】:

使用q! 不起作用,因为在某些时候我已经保存了对该文件的更改。否则我看不到我正在执行的测试的结果。我已经知道如何恢复文件,但不知道为什么 Vim 会添加换行符。感谢您添加到 vimrc 文件中的行。【参考方案3】:

因为vim 是一个文本 编辑器,它有时可以为您“清理”文件。请参阅http://vimhelp.appspot.com/vim_faq.txt.html#faq-5.4,了解如何在没有结尾换行符的情况下编写详细信息,解释如下:

如何编写文件末尾没有换行符 (EOL) 的文件?

您可以关闭eol 选项并打开binary 选项以写入文件末尾没有EOL 的文件::set binary:set noeol:w

或者,您可以使用::set noeol:w ++bin

【讨论】:

感谢您的回答和该链接。这似乎是一个非常有用的常见问题解答集合。【参考方案4】:

我在这里看到的所有答案都解决了“如何防止 Vim 在文件末尾添加换行符?”这个问题,而问题是“为什么Vim 会在文件末尾添加一个新行吗?”。我的浏览器搜索引擎把我带到了这里,但我没有找到那个问题的答案。

这与 POSIX 标准如何定义行有关(请参阅Why should files end with a newline?)。所以,基本上,一行是:

3.206 线 零个或多个非 字符加上一个终止 字符的序列。

因此,它们都需要以换行符结尾。这就是为什么 Vim 默认总是添加一个换行符(因为根据 POSIX,它应该一直存在)。

它不是唯一这样做的编辑器。 Gedit,GNOME 中的默认文本编辑器,做同样的事情。


编辑

许多其他工具也需要换行符。例如:

How wc expects it. GCC warns about it。

另外,您可能感兴趣:Vim show newline at the end of file。

【讨论】:

有时需要一个编辑器,它完全符合用户输入的内容,并且在他没有输入新行的情况下,所以......如果没有新行,这个标准可能会产生问题预期的。这是非常具体的情况,但我更喜欢只有在输入时才有新行。 我学到了一个非常艰难的方法(2 小时的调试),如果没有换行符,tcsh 将不会执行脚本的最后一行。我正在生成 tcsh 脚本的脚本,但忘记在文件中添加最终的 \n 。然后我注意到,如果我只是在 vim 中打开文件,除了保存之外什么都不做,它会突然开始工作。【参考方案5】:

3.206 线 零个或多个非字符加上一个终止字符的序列。

有趣的是,vim 将允许您打开一个新文件,写入该文件,该文件将是零字节。如果您打开一个新文件并使用o 追加一行,那么写入该文件将是两个字符长。如果您打开所述文件备份并删除第二行dd 并写入文件,它将是一个字节长。打开文件备份并删除剩下的唯一行并写入文件,它将是零字节。所以 vim 只会让你写一个零字节的文件,只要它是完全空的。似乎违反了上面的 posix 定义。我猜……

【讨论】:

以上是关于Vim 为啥要在文件末尾添加新行?的主要内容,如果未能解决你的问题,请参考以下文章

Bash Heredoc 格式在 ) 末尾添加新行;

如何防止VSCode自动格式删除json文件末尾的新行?

为啥文本文件应该以换行符结尾?

为啥我必须费心在每个文件的末尾添加换行符?

你能强制 Vim 在文件末尾显示一个空行吗?

VS Code:文件末尾新行不持久