2014-01-14 81 views
1

我想删除gvim中窗口文件中的空行(不是来自cygwin的vim)。

:g/^$/d # delete all blank lines correctly 
:%s/^$//g #can not delete all blank lines 

这是一个问题,如何表达一行的末尾,
我检查了我的文件中详细命令%!xxd
我发现有一个0D0A在每行的末尾,
当行尾由特殊字符$,
表示时是否包含0d0a
它与命令gs之间的表达the end of line的概念是不同的。

:%s/^$\n//g #delete all blank lines correctly 

这让我感到困惑的是^$将包含特殊字符\r\n与否,s命令也许^$不包含3个特殊字符\r\n,但^$g命令来完成,包含3个特殊字符\r\n。 哪个位置做特殊字符$指向?在\r\n之后或在\r\n之前。

回答

7

不,这两个命令是做不同的事情。 :g/^$/d表示“找到空行并删除它们”,而:s/^$//g的意思是“在这条(当前)行中,将所有没有任何东西在线的东西都替换为(仍在同一行)”。正如你注意到的那样,后者是没有意义的。

编辑您的编辑:

^$不包含任何东西。它直接表示“开始行,然后立即行结束”,其中“行”被Vim检测到。 Vim知道\r\n\r\n(取决于文件和创建的操作系统,以及Vim的选项)标记行结束,并相应地对其进行处理。分离器位于之间^$

这就像当你说“我家的房间” - 这(至少对我而言)不包括墙壁。当你说^$\n时,你说的是“空房间,还有旁边的木墙”。 s/^$//是“清空(已空)的房间”; s/^$\n//是“空荡荡的房间,打破了它的墙壁”。

相比之下,对于g,它再次没有说任何关于\n的内容。它找到空行(不关心任何分隔符),然后对其执行一个命令;在你的情况下,命令是d:删除一行。它会删除整行(连同任何换行符)。例如,如果您编写:g/DELETEME/d,它会删除其中包含DELETEME的任何行:它不关心匹配部分中的任何换行符,它只是删除匹配的行。

4

d表示删除匹配的行。 s只是一个替代品。本质上,第二个表达式意思是“用空字符串替代^$的行”,但不会删除它们。你没有任何东西代替。 ^$是零宽度断言,不能被替换。

+0

为什么':%s/^ $ \ n // g'使tasd成功完成? –

+0

@it_is_a_literature,因为'\ n'是一个被替换的匹配字符。谷歌“零宽度断言”。 –

+0

原因:%s/^ $ \ r \ n // g无法运行? –

4

@Amadan和@Explosion Pills都是对的,但我认为你真的需要解释一下“vim如何思考”你正在编辑的内容。

首先,vim基于vi,它是前编辑器的前端。虽然vim已经走过了很长的一段路,但它仍然是一个基于行编辑器的。不要在行尾寻找魔法角色,因为没有! (当我说VIM已经走过了很长的路要走,我记得当添加了'whichwrap'选项。)

我们平时也懒得做了区分,但文件在你的硬盘是从不同在vim中编辑的缓冲区:help buffers)。该文件是一个字符序列(或字节)。当vim读取文件时,它会根据'fileformat'选项(简写为'ff')将它们分成多行。由于您在Windows上工作,因此默认值为'ff'=dos,这意味着文件中的0d0a(也称为CRLF或\r\n)用于分隔行。我有'ff'=unix,所以当我通过xxd筛选时,我只看到0a。 (之前OS   X,Mac使用0d,所以有三个标准!)

这是一个好东西,神奇的EOL字符根本就不存在,因为这使得vim可以在系统之间移植。作为一个基于行的编辑器,vim让你可以做各种各样的事情,比如在每一行中找到第一个模式匹配并对其做些事情。这并不总是你想要的,所以有些人习惯于在每个:s命令的末尾添加/g,甚至设置'gdefault'

回到原来的问题,从缓冲区中删除行与删除行中的所有字符是非常不同的。 Ex命令(记住沿袭)作用于行,并且:d是删除命令。 :s命令将更改一行;不要被普通用法:%s所迷惑,它在缓冲区的每一行(:help :range)上调用:s

相关问题