在vim中将行合并到段落

在vim中将行合并到段落,vim,Vim,我下面有很多行文字。连续行是一段的一部分。但用空行分隔的行是单独段落的一部分。因此,以下文本中有两行内容: first group of lines. first group of lines. first group of lines. first group of lines. first group of lines. first group of lines. second group of lines. second group of lines. second group of

我下面有很多行文字。连续行是一段的一部分。但用空行分隔的行是单独段落的一部分。因此,以下文本中有两行内容:

first group of lines.
first group of lines.
first group of lines.
first group of lines.
first group of lines.
first group of lines.

second group of lines. 
second group of lines. 
second group of lines. 
second group of lines. 
second group of lines. 
second group of lines. 
%s/\n\n\@!//g
我使用以下代码将连续行合并为段落:

first group of lines.
first group of lines.
first group of lines.
first group of lines.
first group of lines.
first group of lines.

second group of lines. 
second group of lines. 
second group of lines. 
second group of lines. 
second group of lines. 
second group of lines. 
%s/\n\n\@!//g
其结果是:

first group of lines.first group of lines.first group of lines.first group of lines.first group of lines.first group of lines.
second group of lines. second group of lines. second group of lines. second group of lines. second group of lines. second group of lines. 
因此,形成段落,但段落之间没有空行分隔。如果我再次运行命令,这些内容也将合并为一个段落。如何修改代码以在新创建的段落之间保留一个空行,以便输出如下:

first group of lines.first group of lines.first group of lines.first group of lines.first group of lines.first group of lines.

second group of lines. second group of lines. second group of lines. second group of lines. second group of lines. second group of lines. 
谢谢你的帮助

:%s/\([^\n]\)\n\([^\n]\)/\1\2/g
他做这项工作

这里使用的是替换组。你在找一个

  • 非新行字符(稍后用\1打印)
  • 新行字符(稍后省略)
  • 非新行字符(稍后使用\2打印)
他做这项工作

这里使用的是替换组。你在找一个

  • 非新行字符(稍后用\1打印)
  • 新行字符(稍后省略)
  • 非新行字符(稍后使用\2打印)
这一条有效(与曼努埃尔·施密特的答案非常相似):

一些解释:

  • 要删除的内容停留在
    \zs
    \ze
    之间(回车
    \n
  • [^\n]
    表示:除回车外的任何字符
因此,该命令的意思是:请删除回车符,但仅当它位于两个非回车符之间时

编辑:来自melpomene的更好的解决方案:

:%s/.\zs\n\ze.//
这一条有效(与曼努埃尔·施密特的答案非常相似):

一些解释:

  • 要删除的内容停留在
    \zs
    \ze
    之间(回车
    \n
  • [^\n]
    表示:除回车外的任何字符
因此,该命令的意思是:请删除回车符,但仅当它位于两个非回车符之间时

编辑:来自melpomene的更好的解决方案:

:%s/.\zs\n\ze.//

考虑到这是一个vim问题,这里有一个vim答案(与正则表达式答案相反)

vim将每个行块视为一个段落,因此您可以从段落中的任何位置输入:

vipgJ
这将直观地选择段落(
vip
)并连接所有行,而不添加或删除空格(
gJ

下面是一种创建宏的方法,该宏连接当前段落,然后移动到下一个段落,准备再次运行:

qqvipgJjjq
现在使用
@q
运行宏。如果您知道要运行它多少次,可以使用该数字作为前缀
5@q
,或者只需输入一个大数字即可将其应用于文档的其余部分

对于一个非常酷的技巧,您甚至可以编写宏来递归地调用自己。它将不断调用自己,直到不再进行更改为止-在这种情况下,当它到达文档末尾时(在开始此操作之前,请确保您的
q
寄存器为空,否则您将在编写新宏时应用现有宏-您只需键入
qq
)即可将其清除:

说明:

  • qq
    :开始将宏记录到寄存器“q”中
  • vipgJ
    :加入当前段落
  • jj
    :下移2行到下一段
  • @q
    运行宏“q”(录制时不执行任何操作,因为寄存器“q”为空)
  • q
    :停止录制宏
  • @q
    :运行宏

    • 考虑到这是一个vim问题,这里有一个vim答案(与正则表达式答案相反)

      vim将每个行块视为一个段落,因此您可以从段落中的任何位置输入:

      vipgJ
      
      这将直观地选择段落(
      vip
      )并连接所有行,而不添加或删除空格(
      gJ

      下面是一种创建宏的方法,该宏连接当前段落,然后移动到下一个段落,准备再次运行:

      qqvipgJjjq
      
      现在使用
      @q
      运行宏。如果您知道要运行它多少次,可以使用该数字作为前缀
      5@q
      ,或者只需输入一个大数字即可将其应用于文档的其余部分

      对于一个非常酷的技巧,您甚至可以编写宏来递归地调用自己。它将不断调用自己,直到不再进行更改为止-在这种情况下,当它到达文档末尾时(在开始此操作之前,请确保您的
      q
      寄存器为空,否则您将在编写新宏时应用现有宏-您只需键入
      qq
      )即可将其清除:

      说明:

      • qq
        :开始将宏记录到寄存器“q”中
      • vipgJ
        :加入当前段落
      • jj
        :下移2行到下一段
      • @q
        运行宏“q”(录制时不执行任何操作,因为寄存器“q”为空)
      • q
        :停止录制宏
      • @q
        :运行宏

      对其工作原理进行一些解释会有所帮助。在使用这段代码时,有什么情况需要注意吗?实际上@yolenoyer发布的这段代码似乎更适合于解释它是如何工作的。使用此代码时有什么情况需要注意吗?实际上@yolenoyer发布的代码对我来说更合适。您可以使用
      而不是
      [^\n]
      @melpomene:'。”表示任何意思。为什么不删除空行,即将“\n\n下一行”替换为“\n下一行”
      表示除行尾以外的任何字符(请参阅Vim的帮助)。最后,它与
      [^\n]
      非常相似,
      g
      仅当每行有多个匹配项时才有用;这里不是这样。请仔细阅读帮助以了解更多信息,谢谢您可以使用
      而不是
      [^\n]
      @melpomene:'。'