考慮する:
foo
bar
....
bar
baz
それから:
:g/bar/s/\n/\r\r/g
予期しない収益:
foo
bar
bar
bar
bar
bar
...
baz
各後ろに新しい行が必要なときbar
。しかし:
:g/bar/p
返品:
bar
bar
...
bar
期待どおりにすべてのsの間に改行文字がある場合、bar
期待される結果が得られます。各行には、次bar
の方法で問題を解決しました。
:%s/\(bar.*\)\n/\1\r\r/g
しかし、私は何が起こっているのかをよりよく理解したいと思います。
答え1
このレベルの詳細を理解するには、ソースコードを取得する必要があると思います。したがって、引用してくださいvim-7.1.314/src/ex_cmds.c
(ヘッダーを定義するコメントex_global()
)。
これは2つのステップで行われます。まず、ファイルからパターンを検索し、一致する(一致しない)各行にフラグを設定します。次に、表示された各行でコマンドを実行します。これは、行を削除した後に次の一致を検索する場所がわからないために必要です。
したがって、'edコマンドから1行を削除すると、:g
その行の表示も消えます。 'ed コマンドに行を作成すると:g
表示されないため、コマンドは実行されません。例では、行3は行2にリンクされているため、行3のマーカーは消え、行2の後のマーカーは元の行4に配置されたマーカーです。
また、変数がex_global
設定され、一部のコマンド(含まれている)が少し異なる動作をしますglobal_busy
。:s
しかし、ここではその違いは重要ではないと思います。
答え2
ザイルズすでに「なぜ?」に答えていますが、欲しいものを達成するためのより簡単な方法に興味があると思いました。
私はそれぞれ次に新しい行が欲しいです
bar
。
行終端文字を置き換える代わりに(したがって行を連結し、Gilesの回答に従って内部トークンが失われる)、一致する各行の最後の前に空の行を追加します。$
行が終わる前に幅が0の一致を取得するために使用され、そこに改行文字を挿入します(/g
パターンは1行に1回だけ一致するため、修飾子は必要ありません)。
:g/bar/s/$/\r/