Vim:如何删除每隔一行?

时间:2009-12-22 14:35:55

标签: vim

如何在Vim中执行此操作:

在:

aaa
bbb
ccc
ddd
eee
fff

在:

aaa
ccc
eee

13 个答案:

答案 0 :(得分:233)

完成任务的一种优雅(高效)方式是发布 :+delete命令删除每行上当前行旁边的行 使用:global命令。

:g/^/+d

答案 1 :(得分:95)

您可以使用宏来实现此目的。执行以下操作。

  • 以命令模式启动。
  • gg
  • 转到文件的开头
  • qq
  • 点击向下箭头,然后按dd
  • q
  • 10000@q

PS:要进入命令模式,只需按Escape几次。

答案 2 :(得分:60)

我们可以使用:normal:norm来执行给定的普通模式命令。 Source.

:%norm jdd

答案 3 :(得分:10)

:map ^o ddj^o
^o

这里^代表CTRL。 递归宏每两行删除一行。选择好你的第一行就完成了。

答案 4 :(得分:7)

来自vim mail archive

:let i=1 | while i <= line('$') | if (i % 2) | exe i . "delete" | endif | let i += 1 | endwhile

(要在vim命令行的一行输入,将删除行1,3,5,7,...)

答案 5 :(得分:5)

您可以随时通过shell命令进行管道传输,这意味着您可以使用任何您喜欢的脚本语言:

:%!perl -nle 'print if $. % 2'

(或使用“除非”代替“如果”,具体取决于您想要的那些行)

答案 6 :(得分:4)

:%!awk -- '++c\%2'

替代地

:%!awk -- 'c++\%2'

取决于你想要除草的那一半。

答案 7 :(得分:3)

答案 8 :(得分:3)

您可以使用Vim自己的搜索和替代功能,如下所示: 将光标放在第一行,然后键入正常模式:

:.,/fff/s/\n.*\(\n.*\)/\1/g
  • .,/fff/是替换的范围。它表示“从此行到与正则表达式fff匹配的行(在本例中为最后一行)。
  • s///是替换命令。它查找正则表达式并用字符串替换它的每一个匹配项。只要正在找到正则表达式,最后的g意味着重复替换。
  • 正则表达式\n.*\(\n.*\)匹配换行符,然后整行(.*匹配除换行符之外的任意数量的字符),然后是另一个换行符和另一行。括号\(\)会导致其中的表达式被记录,因此我们稍后可以使用\1来使用它。
  • \1插入分组的换行符和后面的行,因为我们不希望下一行也消失了 - 我们只是希望替换机制通过它,所以我们不会删除它下次更换。

通过这种方式,您可以控制要进行删除的范围,而不必使用任何外部工具。

答案 9 :(得分:3)

作为另一种方法,如果你的vim支持它,你也可以使用python。

:py import vim; cb = vim.current.buffer; b = cb[:]; cb[:] = b[::2]

b = cb[:]暂时将当前缓冲区中的所有行复制到bb[::2]从缓冲区获取每一行,并将其分配给整个当前缓冲区cb[:]。复制到b是必要的,因为缓冲区对象似乎不支持扩展切片语法。

这可能不是“vim方式”,但如果你知道python,可能会更容易记住。

答案 10 :(得分:2)

删除奇数行(1,3,5,..) - &gt; :%s/\(.*\)\n\(.*\)\n/\2\r/g

删除偶数行(2,4,6,..) - &gt; :%s/\(.*\)\n.*\n/\1\r/g

搜索文本(形成第一行),然后是新行字符和更多文本(形成第二行),后跟另一个新行字符,并将上面的内容替换为第一个匹配(奇数行)或第二个匹配(然后回车。然后回车。

答案 11 :(得分:0)

你可以在vim中试试这个

:2,$-1g/^/+1d

答案 12 :(得分:0)

调用sed:

:% !sed -e '2~2 d'

^^^^                  pipe file through a shell command
    ^^^^^^            the command is sed, and -e describes an expression as parameter
            ^^^^^     starting with the second line, delete every second line