Answers:
问题的可能解释
我认为:g/;/j
不起作用的原因是该:g
命令使用2遍算法进行操作:
;
在第二遍过程中,由于在第一遍过程中被标记,因此与line :g
连接1;
起来。但是我怀疑(不确定)它不加入,因为该行不再存在,它的内容已经与已经处理过的行合并了。 2;
1;
1; 2;
3;
2;
1;
因此,:g
寻找在第一遍(3;
)期间标记的下一行,并将其与下一个(4;
)连接起来。之后,问题再次出现3; 4;
,5;
因为该行4;
不再存在,因此无法加入。
解决方案1(带vimscript)
也许只要;
找到包含的行,就可以调用函数来检查前一行是否也包含分号:
function! JoinLines()
if getline(line('.')-1) =~ ';'
.-1join
endif
endfunction
然后使用以下全局命令:
:g/;/call JoinLines()
或没有功能:
:g/;/if getline(line('.')-1) =~ ';' | -j | endif
解决方案2(无vimscript)
:g/;/.,/^[^;]*$/-1j
每当全局命令:g
找到模式时,;
它都会执行命令: .,/^[^;]*$/-1j
可以这样分解:
:g/pattern/a,bj
哪里:
pattern = ;
a = . = number of current line
b = /^[^;]*$/-1 = number of next line without any semicolon minus one
b
可以进一步细分如下:
/ = look for the number of the next line matching the following pattern
^ = a beginning of line
[^;] = then any character except a semicolon
* = the last character can be repeated 0 or more times
$ = an end of line
/ = end of pattern
-1 = removes one to the number you just got
j
是Ex命令的缩写形式:join
,与大多数其他Ex命令一样,它可以以范围开头。
这里它是由前面范围:.,/^[^;]*$/-1
(a,b
)
甲范围如下的形式a,b
,其中a
和b
通常是2个号,并允许在一组线,其数量是之间的操作a
和b
,而不是仅仅一个。
因此,该j
命令将当前一个(a
)和下一个不包含任何分号减一个(b
)的下一行之间的所有行连接起来。
有关更多信息,请参见:
:help :global
:help :join
:help :range
我一直通过全局搜索和替换来进行类似的加入:
s /; \ n /; /
\n
匹配换行符。
查找和删除空白行:
s / ^ $ \ n //
我不确定为什么,但是如果要插入新行,则必须使用 \r
s
单独将只适用于一条线,要使其成为全局线,您需要使用%s
,但是它将加入几乎所有线,包括非;
线
:s
命令。我认为这%s/;\n\(.*;\)\@=/;/
可以满足您的需求。
:g/;/j
不起作用,因为它分两步完成:首先扫描缓冲区,然后将命令应用于匹配的行。