从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<CR>
比使用 "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的寄存器中删除换行符?的主要内容,如果未能解决你的问题,请参考以下文章