如何删除每隔一行,加上选中后粘贴删除的结果?

时间:2012-07-06 04:06:41

标签: vim

这是question about deleting every second line in a file的后续内容。

如何在Vim中执行此操作:

之前(说它是文件的VISUAL选择的一部分):

aaa
bbb
ccc
ddd
eee
fff

在:

aaa
ccc
eee
bbb
ddd
fff

如何执行此宏样式(删除所有其他行,但将已删除的行存储到缓冲区,以便按顺序粘贴已删除的行)?

另外,如果你能在VISUAL选择中做到这一点,那将非常方便(解析某个文件)!

4 个答案:

答案 0 :(得分:3)

当要重新排序的行是缓冲区中唯一存在的行时,运行 命令

:g/^/+m$

通常,当这些行被其他文本包围时,也可以 选择要重新排序并运行的目标行范围

:exe"'<,'>g/^/+m"line("'>")

或选择要重新排序的所有行,但选择其中第一行并运行

:'<,'>-g/^/+m'<-

在任何一种情况下,重新排序都是在一次运行中有效完成的。

答案 1 :(得分:2)

  1. 键入:let @e=''<CR>以清空e个注册表(假设您不关心其先前的内容)。

  2. 将光标放在aaa

  3. 输入qa(或任何其他字母而非a)来记录您的宏。

  4. 键入j"Edd以向下移动一行并将其删除,同时将其附加到e注册表。

  5. 键入q以停止录制

  6. 直观地选择整个事物。

  7. 使用:'<,'>norm @a<CR>应用宏,这将删除所有其他行。

  8. 输入"ep

答案 2 :(得分:2)

你真的不需要一个宏。

我们需要一个临时寄存器来输入结果,比如注册e(如proposed by romainl)。

  1. 清空寄存器(寄存器必须为空,因为我们要使用大写的寄存器名称,这意味着要附加而不是覆盖)
    :let @e='' 输入
  2. 直观地选择要处理的区域(即行aaafff
  3. 删除每隔一行并将该行追加到注册e
    :g/^/+d E
    现在,注册e包含已删除的内容
  4. 使用e
  5. 粘贴注册"ep

    讨论

    • 我们需要在使用它之前清空寄存器,因为我们使用大写的寄存器名称,这意味着要附加到寄存器(参见{{3}上的命名寄存器部分) })

    • 输入:he registers了解有关令人难以置信的强大:g命令的更多信息(以及它并不是那么有用的朋友:he :global

    • :v已经涵盖了99%的实际答案,但遗憾的是未被接受,但对您引用的问题的答案非常好。您需要的唯一扩展是累积已删除的行而不是丢弃它们(确切地说:将最后删除的行存储在默认寄存器中)

答案 3 :(得分:2)

尝试此命令:

:'<,'>g/^/+m$

它会将它们移动到文件末尾。然后你可以轻松地将它们移回去。