問題の考えられる説明
:g/;/j
動作しない理由は、:g
コマンドが2パスアルゴリズムで動作するためです。
- 最初のパスでは、パターンを含む行をマークします
;
- 2番目のパスでは、マークされたラインで動作します
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
Exコマンドの省略形で、:join
他のほとんどのExコマンドと同様に、範囲を前に付けることができます。
ここでは、範囲が先行しています:.,/^[^;]*$/-1
(a,b
)
範囲の形式以下と一般に2行番号であるが、あなたは番号の間にある行のグループ上で動作することを可能にすると、代わりに一つだけの。 a,b
a
b
a
b
したがって、このj
コマンドは、現在の行(a
)と、セミコロンから1を引いたものを含まない次の行()までのすべての行を結合しますb
。
詳細については、以下を参照してください。
:help :global
:help :join
:help :range
:g/;/j
は2つのパスで行われるため機能しません。最初にバッファがスキャンされ、次にコマンドが一致する行に適用されます。