如何让Vim处理我的命令?

时间:2013-04-03 05:53:46

标签: vim

假设我有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可以从后到前处理,这不会发生,我可以得到我想要的结果。

顺便说一句,我可以通过其他方式获得预期的结果,我只是想知道这是否可行。

4 个答案:

答案 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"}'