假设我有5行文本,如果我输入一些命令让vim处理每一行,Vim将逐个处理文本,第一行,第二行,......最后一行。我想要的是让Vim以相反的顺序处理我的文本。这是最后一行,然后是第4行,最后是第一行。
为什么我需要这个? 我有以下文字
1234567890
abc
123
def
1234567890
123456789
我想从包含3个字符的行中删除换行符号(\ n)。所以在处理之后,我将得到以下文字
1234567890
abc123def1234567890
123456789
这似乎是小菜一碟,我使用以下命令
:%s/\v(^\w{3})\n/\1/
但我得到的是
1234567890
abc123
def1234567890
1234567890
为什么呢?我想vim首先从第二行删除\ n,然后这行有文字abc123,现在vim不会删除123之后的\ n,因为它现在不是3个字符,所以vim处理下一行def,并从中删除\ n那是我得到的结果。
如果vim可以从后到前处理,这不会发生,我可以得到我想要的结果。
顺便说一句,我可以通过其他方式获得预期的结果,我只是想知道这是否可行。答案 0 :(得分:2)
可以使用perl实现:
while (<>) {
chomp if (/^...$/);
print;
}
答案 1 :(得分:2)
向后循环显示行范围(例如,视觉上选择的行),然后在每行上执行命令。我在这里使用了:join
而不是带有换行符的:substitute
:
:for i in range(line("'>"), line("'<"), -1)| silent execute i . 'g/^\w\{3}$/join!' | endfor
答案 2 :(得分:1)
在这种情况下,使用:global
命令加入行更容易。
:g/^\w\{3}$/normal! gJ
命令gJ
将当前行与以下行连接,而不插入任何空格。上面的全局命令在每行只包含三个字符时调用gJ
。它通过在执行操作之前首先标记所有匹配来工作,因此避免了循环问题。
答案 3 :(得分:1)
这一行应该做你想做的事:
:%s/\v(\_^\w{3}\n)+/\=substitute(submatch(0),"\n","","g")/
如果你想用外部命令更简单,例如awk,你可以:
%!awk '{printf "\%s", length($0)==3? $0:$0"\n"}'