回答:
Vimの:gコマンドは、まさにこの種のタスク用に設計されています。特定のパターンに一致するすべての行で単一のアクションを実行します。私の答えは次のとおりです。
:g/.\n\n\@!/norm o
私が使用するパターンは/.\n\n\@!/
です。それをコンポーネントに分解します:
.
行の任意の文字に一致します。(既存の空行を考慮から直ちに破棄するために使用されます)\n
上の文字の末尾にある単一の\ nと一致します\n\@!
前の\ nの直後に別の\ nがある場合、一致は失敗します。(正規表現の:h E59
詳細\@!
および類似の一致指定子を確認してください。他にもいくつかあります!)
したがって、:gコマンドの正規表現は、単一の改行で終了し、その後に空の行が続かない空ではないすべての行を選択するようになりました。
:g
ステートメントのパターンの後に、一致する行で実行するコマンドがあります。この場合、通常モードのコマンド(と略記norm
)を実行するように指示しましたが、実行するコマンドは単にo
で、現在の行の下に空の行を挿入します。
このようにまとめると、コマンドはその下に空の行がないすべての行を検出し、追加します。そして、それはそれだけです!vim wikiのPower of Gの記事でもっとおしゃれなことができるかどうかを確認することもできます:g
(そして、それは否定的な姉妹です:v
)。持っていない
:%s/$/
から、ヒット^V
してからヒットしEnter
ます。
:%s/$/<C-V><CR><CR>
(キープレスの一般的なvimフォークエンコーディングを使用することを意味する)と仮定すると、そのアプローチは各行の後に改行を追加するだけです。つまり、すでに空白で区切られている行(テキスト例の行3->行4を参照)は、余分な空白行を取得します。最初の質問は、開始テキストにすでに存在する余分な空白行を追加しないようにすることでした。
@NeilForesterのグローバル検索と置換応答をテストしたとき、行に各文字が1文字しか含まれていない場合、連続する非空白行で1秒おきに意図した置換を見逃していることがわかりました。これは、パターンが前の機会に一致した最後の文字の後、各機会に一致し始めたためであると思われます。
先読みと先読みを使用すると、この問題が解決され、正規表現も少し短くなります。
:%s/\n\@<!\n\n\@!/\r\r/g
\n\@<!\n
、別の改行の直後ではない改行が正しいことを意味しますか?しかし、私は何を\n\@!
意味するのか理解できませんでした。私はそれを理解して、他の検索パターンにそれを学び、適用できるようにしたいと思います:)
\n\@<!\n
別の改行の直後に続かない改行を意味します。\n\@!
先行するアトム(つまり\n
)が直後のアトムと一致しない場合、幅0で一致 :help \@<!
vimでこれに関するドキュメントを参照してください。私
/[^\n]\n[^\n]
:map <F2> no<esc><F2>
次にを押し<F2>
ます。これにより、2つの連続する非空白行が検索され、その間に行が繰り返し追加されます。
編集:
単一のグローバル検索と置換を使用する別の方法を次に示します。
:%s/\([^\n]\)\n\([^\n]\)/\1\r\r\2/g
:%norm o
これはの場合に意図したとおりに機能しないことがわかりo
ます。1