从vim的寄存器中删除换行符?

Posted

技术标签:

【中文标题】从vim的寄存器中删除换行符?【英文标题】:remove newlines from a register in vim? 【发布时间】:2011-09-07 20:33:31 【问题描述】:

我有一长串不同的大学名称。我正在尝试通过将行与某些唯一关键字进行比较来构建同义词表;也就是说,在文件中,我会确定哈佛是这里的关键字:

Harvard Business School|
Harvard College|
Harvard School of Divinity|

并将它们粘贴到另一个文件中

Harvard Business School|Harvard College|Harvard School of Divinity|

我一直在通过搜索光标下的单词,将带有该单词的行拉到寄存器中,将寄存器粘贴到另一个文件中,然后使用连接命令“J”将这些行连接在一起:

[ clear register 'a' ]    
0"ay0
[ move cursor to 'Harvard" and yank lines with keyword into register a ]
:g/\<<CTRL-R><CTRL-W>\>/y A
[ move to other screen and paste ]
"ap
[ join lines ]
JJJJJ

这很好用,但我希望它能够简化。具体来说,我想知道如何从寄存器中删除换行符,这样我就不必在最后一步使用 JJJJ 手动加入行。我想搜索包含光标下单词的所有行,将它们复制到“a”寄存器中,从“a”寄存器中删除换行符,然后粘贴“a”寄存器的内容。

有什么想法吗?

编辑: 我知道:

如何全局搜索和替换,例如%s/\n//g 如何在缓冲区中搜索和替换 'foo' 从单词到寄存器的内容,例如:%s/foo/a/g 如何搜索寄存器的内容并在缓冲区中替换为 'foo',例如:%s/a/bar/g

我需要知道的:

如何从寄存器 'a' 中搜索 'foo' 并将其替换为 'bar' 到寄存器 'b' 如何从寄存器“a”中搜索“foo”并将其替换为“bar”以注册“a”

【问题讨论】:

这必须在vim中完成吗?相反,如果你有一个分隔列表,这可以很容易地在 awk、python、sed、perl 等中完成。相反,这个列表是标准的,例如一所学校、一根管道和每行一个“\n”吗?或者每行是否包含其他信息? 只是学校和管道在线。我的问题实际上是关于 vim 而不是关于如何使用其他工具解决问题;我只提供了上下文的问题(并查看是否有任何其他 vim 解决方案)。 很公平,我在下面提供了我的解决方案。 【参考方案1】:

如果我可以假设您的文本文件如下所示:

哈佛商学院| 哈佛 学院| 哈佛神学院|

我会用

:%s/\n//g

全局搜索并替换所有 \n 新行。 有时,您可能需要使用 ^M(按 control+v 和 ENTER) 代替\n。

恐怕您的列表可能比这个更复杂,但是,在这种情况下,我的解决方案将过于“简单”

【讨论】:

恐怕这不起作用,因为换行符在两个文件中传输信息。在 copyto 文件中,我不希望所有大学都在一条线上,我只希望在一条线上实际上相同的大学 - 这就是问题的重点(搜索并替换 in registers) . 哦,我明白了。我现在知道了。等一下,我会再回来回答。可能需要几分钟...看看我的工作情况【参考方案2】:

要直接使用寄存器a 中的文本,您可以使用以下命令:

:let @a=substitute(strtrans(@a),'\^@',' ','g')

然后,当您将注册 a 粘贴回来时,您应该会得到您想要的结果。

【讨论】:

你能解释一下这里发生了什么吗?我了解 let @a=substitute(strtrans(@s) 部分,只是不了解替代()的中间两个参数 这几乎可以做到,但它在每个附加行的开头添加了多余的^@:^@Adelphi University|^@Adelphi College| - 我不确定 \^@ 的含义或如何在 google 或 vimhelp 中查找它。 @Peter -- 我的想法是这样的:寄存器中的多行文本没有 ^M 字符,而是每行都以空字符 '^@' 结尾。要为该字符替换一个空格,您首先需要使用 strtrans() 将其转换为两个字符文字,^@^@ 前面的反斜杠是所以 ^ 不会被读取为“行首”特殊字符。所以发生的事情是(1)空字符被转换为两个字符^@,然后每个出现的两个字符序列都被替换为空格字符。不知道为什么 final arg 不必是全局标志 ('g') 但它似乎可以工作。 感谢您的解释。知道为什么 ^@ 结果会出现在输出中 - 任何摆脱它们的方法?我已经阅读了***.com/questions/71323/… 和***.com/questions/71323/…,但仍然不清楚我必须做什么才能使其正常工作。 @Peter -- 不,^@ 不应该显示。它们是因为您确实需要将“g”标志设置为替代的最后一个参数。我更改了答案以反映这一点。【参考方案3】:

您不需要从寄存器中删除换行符或按多个J:使用以下映射,它将是"apgVJ

nnoremap <expr> gV    "`[".getregtype(v:register)[0]."`]"

此映射使您能够在粘贴后选择粘贴的文本。选定区域上的J 加入区域中的所有行(除非区域只有一行:这里J 就像J 没有选择,将当前行与下一行连接起来)。 gV 提示也可用于替换:"apgV:s/pattern/replacement&lt;CR&gt; 比使用 "ap:let @a=substitute(@a, 'pattern', 'replacement', 'flags') 更方便,除非您定义了一些智能映射。

另一个提示是寄存器a 可以使用qaq 正常模式序列清除:qa 开始记录一个新宏,q 立即停止它,在a 寄存器中留下空字符串,宏被记录到.

【讨论】:

【参考方案4】:

游戏迟到了,但因为其他人似乎都解决了错误的问题 由于谷歌为我遇到的问题提供了解决方案, 我觉得有义务提供我的解决方案。

将模式匹配累积为"a 中的一行

    :g/pattern/ norm "apkJ"addu

或使用未命名的寄存器

    :g/pattern/ norm pkJddu

它不会删除寄存器中的换行符,因为它不是必须的。

如果您删除规范代码末尾的u,它将消耗文件中已使用的行,这可能会使文件的手动处理更容易,因为您不必阅读内容已经处理好了。

引用:

   [ join lines ]
   JJJJJ

一个问题,为什么不使用5J、可视模式或:%j(连接文件中的所有行)?

离题:

    "How do you mark text between "" in code blocks,
    not to be colour coded?"

【讨论】:

以上是关于从vim的寄存器中删除换行符?的主要内容,如果未能解决你的问题,请参考以下文章

vim 处理换行符

vim 的换行问题

vim常用命令总结

vi-vim :删除撤销恢复删除复制删除

vim命令总结

vim经常使用命令总结