문제에 대한 가능한 설명
:g/;/j
작동하지 않는 이유 는 :g
명령이 2 패스 알고리즘으로 작동 하기 때문입니다 .
- 첫 번째 패스 동안 패턴을 포함하는 라인을 표시합니다.
;
- 두 번째 패스 중에는 표시된 라인에서 작동합니다.
두 번째 패스 동안에, :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
은 :join
다른 Ex 명령과 마찬가지로 범위가 앞에 올 수있는 Ex 명령 의 약식 입니다.
: 여기가 범위 앞에있어 .,/^[^;]*$/-1
( a,b
)
범위의 형식은 다음 과 일반적으로 2 개 라인의 숫자를, 당신이 줄 수 사이의 그룹에서 작동 할 수 있도록 하고 대신 하나. a,b
a
b
a
b
따라서 j
명령은 현재 행 ( a
)과 세미콜론 빼기 ( b
)를 포함하지 않는 다음 행 사이의 모든 행을 결합합니다 .
자세한 내용은 다음을 참조하십시오.
:help :global
:help :join
:help :range
:g/;/j
는 두 단계로 이루어지기 때문에 작동하지 않습니다. 먼저 버퍼를 스캔 한 다음 명령을 일치하는 줄에 적용합니다.