Vim为什么要添加换行符?这是惯例吗?


22

如果我打开Vim并键入,itest<Esc>:wq那么我会得到一个文件,该文件在Vim中没有换行符但是在代码中似乎确实有换行符:

$ vim -u NONE test.txt
$ cat test.txt | hd
00000000  74 65 73 74 0a                    |test.|
00000005

如果我打开Vim并键入,itest<Return><Esc>:wq那么我将得到一个文件,该文件在Vim中有一个换行符但是在代码中有两个换行符:

$ rm test.txt
$ vim -u NONE test.txt
$ cat test.txt | hd
00000000  74 65 73 74 0a 0a                 |test..|
00000006

请注意,我使用打开Vim,-u NONE所以没有使用本地配置。还请注意,这可能与我先前的问题有关

这是我的系统信息:

$ uname -a
Linux awsAlpha 3.2.0-60-virtual #91-Ubuntu SMP Wed Feb 19 04:13:28 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ vim --version
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled May  4 2012 04:25:35)
Included patches: 1-429
Modified by pkg-vim-maintainers@lists.alioth.debian.org
Compiled by buildd@

我也可以在此系统上确认完全相同的行为:

$ uname -a
Linux bruno 3.5.0-48-generic #72-Ubuntu SMP Mon Mar 10 23:18:29 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ vim --version
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Oct 26 2012 16:45:33)
Included patches: 1-547
Modified by pkg-vim-maintainers@lists.alioth.debian.org
Compiled by buildd@

Vim为什么要添加换行符?这是惯例吗?

以下是有关hd在Ubuntu Server上安装的命令的一些说明:

$ man hd | head -4
HEXDUMP(1)            BSD General Commands Manual            HEXDUMP(1)

NAME
     hexdump, hd — ASCII, decimal, hexadecimal, octal dump

8
这似乎是惯例。以下是如何禁用它,如果你想要的。这是历史。
jliv902 2014年

Answers:


28

Unix文本文件的约定是,每一行都以换行符结尾,并且换行符是行终止符,而不是行分隔符。

当Vim将缓冲区另存为文件时,它将以该文件格式的行尾序列终止每一行,对于Unix,这是换行符。看到

:help 'fileformat'

如果您使用的是Unix文本处理工具,则最好遵循此约定。但是,如果您有一些需要不将换行符放在文件最后一行的末尾,则可以这样做。Vim认为此类文件为“二进制”。看到

:help 'binary'
:help edit-binary

1
哦,这很有趣。因此,除了著名的\ r \ n与\ n。Windows使用行分隔符,而Unix使用行终止符?并记录在任何地方吗?我知道它的定义大概适用于unix“ ISO / IEC 9899:2011,第§7.21.2节流说:文本流是由行组成的有序字符序列,每行包含零个或多个字符以及一个终止符行字符”
barlop

但是在哪里记载Windows使用行分隔符?
barlop 2014年

2

Vim不会添加您自己没有放置的任何内容。

“换行”字符不是 “换行”,并且两个示例都完全正常:

  • 在第一个文件中,文件仅包含一行,因此您将获得一个“换行符”,
  • 在第二个文件中,文件包含两行,因此您将获得两个“换行符”。

2
它确实添加了换行符。请按以下步骤进行测试:printf "\x41" > /tmp/test.txt,然后检查是否只有一个'A'字符xxd /tmp/test.txt。现在vim /tmp/test.txt<ENTER>:wq。再次检查以查看文件有两个字节:“ A \ n”。
Ruslan 2014年

行以换行符结尾。您只有一行,因此只有一个换行符。
romainl 2014年

好吧,在printf这里之后,我没有格式正确的“线条”。vim之后我有一个。因此,它确实添加了一些我没有放在那的东西。
Ruslan 2014年

什么你printf,除非你追加是不是一条线\n。作为一个文本编辑器,在默认情况下行时Vim交易,任何你在文件中插入文本对,起码,行,除非你明确地告诉Vim不会这样做。
romainl 2014年

2

未终止的文本文件是有害的,原因有多种。这是我还没有看到的一个:

在假设的世界中,不带尾随换行符的文本文件是可以接受的,那么包含0行的文件和包含1空行的文件之间就不会有任何区别。它们都将由一个0字节的文件表示。

无法确定文件中有多少行会很糟糕。


在非Unix系统中,文本文件包含零个或多个完整的行,以及一个零个或多个字符的不完整的行。空文件不包含空行;它包含零个完整行和零个字符的部分行。歧义在哪里?
2014年

这种“分界线”是不愉快的概念。除了文件末尾,您在任何地方都不能拥有一个文件,也不能创建没有 “分行”的文件。它增加了文件串联的破损-即使您在文件之间插入换行符,最终在语义上也不等同于原始文件对(因为2个文件中有2个分行,其中一个变成了分行)不一样。)

在两个文件都包含全行的情况下,串联文件会导致第一个文件末尾的任何部分行都加到下一个文件的事实通常比较棘手(有时串联不包含任何全行的文件可能会很有用), 但是它就是这样啊。Unix禁止构建以分行结尾的文本文件,我相信串联此类文件的行为将与MSDOS相同。我认为的区别是,许多基于DOS的编辑器历来都认为加载并立即保存文件应产生一个新文件...
supercat 2014年

...这与旧版本完全相同(早期PC-Write版本的注册用户被指示使用它来打开可执行文件的副本,切换到覆盖模式,找到某个字符串,然后将其替换为序列号!)。保存文件时强制文件以换行符结尾会违反该约束。
supercat 2014年

2

Vim 8.0现在为此提供了fixeol选项。特别是如果您这样做:

:set nofixeol

如果文件中没有Vim,Vim 不会在最后一行的末尾添加尾随换行符。

那可以放在文件类型的插件中,甚至可能在您的中.vimrc

(这是一项改进,:set binary因为它仅影响最后的换行符,同时binary还改变了许多其他行为,除非您实际上正在编辑二进制文件,否则您可能不希望这样做。)

默认情况下,新创建的文件仍将带有换行符。您可以通过以下操作将其更改(并将已经有最后一个换行符的文件切换为没有该文件):

:set noeol

必须为您要更改的每个文件专门设置该设置:将文件加载到缓冲区中将始终设置eol为与文件的当前状态匹配。


1

使用“ j”命令,您可以将所有行合并为一个。

如果还要删除最后一行的LF或CRLF,请执行vi中的以下操作。

$ vi file
:set binary
:set noeol
:w!
:f          look for [noeol] on the status line
:q
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.