Vim:sは、行の最初のN <gオカレンスを置き換えます


13

vimでは、行の最初の数件の一致を置き換える機会がある場合がありますが、すべてのユーザーがそうするわけではありませんg。例えば:

a a a a a

b b b a a

私はを使用できることを知っていますが:s/a/b/[enter]:[up][enter]:[up][enter]、3回の繰り返しでは十分に退屈です。
私はもう試した:

  • :s/a/b/3g:vimが末尾の文字について不平を言いました。
  • :s/a/b/3:この最初の出現と、それに続く2行を変更します。
  • 3:s/a/b:前と同じ。
  • :s/a/b/g3:これと次の2行のすべての出現箇所を変更します。
  • :3s/a/b:3行目の最初の出現箇所を変更します。
  • :/a/,3/a/s/a/b:ファイルにa含まaれる次の行と3番目の行の間の各行の最初の出現を変更します(必要に応じて反転するように要求します)。
  • :/a/,/\([^a]*a\)\{3\}/s/a/b/:これと次の行の間の各行の最初の出現箇所を3 a秒で変更します(これは、複数文字の検索に簡単に拡張できなかったでしょう)。

その他のさまざまなアドレス指定パターンがあり、どれも機能しませんでした。:sこの問題の答えを見つけようとするコマンドについてはかなりのことを学びましたが、まだ解決していません。

誰でもこれを行う方法を知っていますか?

(特定の範囲のボーナスポイント、たとえば2番目から4番目の出現)


2
vimではそれができないと思いますが、退屈さを減らすために、「n」と「。」について知っていますか。ビジュアルモードで?つまり、/ pattern /を使用して変更するものを見つけ、「cw」などを使用して変更し、次に「n」(nのみ、引用符なし)を使用して次のパターンを検索し、「。」を押します。(ピリオドのみ、引用符なし)最後の編集を実行します。
Bruce Ediger、

@BruceEdigerについては知っていましたがn.ここではそれらを使用するつもりはありませんでした。確かに改善に感謝します。
Kevin

s/a/=something/トリック(:help sub-replace-=)を実行する必要があります。私はVimで流暢に書くのに十分な流暢ではありませんsomething
Gilles「SO-悪をやめなさい」

注::[up][enter]はで置き換えることができますが&、これはまだ理想的ではありませんが、少なくとも痛みは少なくなります。
Kowh、2011

回答:


10

:s/pattern/replacement/gc Samus_からアイデアに基づいて(パターンが置換文字列内に含まれている場合に正しい操作を保証する最も簡単な方法のようです)、1行で2番目から4番目のオカレンスを置き換えます。

:call feedkeys("nyyyq") | s/pat/string/gc

feedkeys()入力文字列をキーボード入力キューに詰め込む関数です。重要なのは、カウントを前もって行うことです。これにより、カウントの喪失や中断を心配する必要がなくなります。

より一般的なケースでは、Nが非常に大きいM以上の場合、単一行のM番目からN番目のオカレンスを置き換えます。

:call feedkeys(repeat("n", M-1) . repeat("y", N-M+1) . "q") | s/pat/string/gc

MNを必要な値に置き換えます(vim自分でやりたくない場合は、簡単な暗算を行うこともできます)。注.VIMLの文字列連結演算子です。明らかに、これは大きなMのキーストロークのみを保存します。この機能を頻繁に使用する場合は、タイプするのがかなり難しいので、上記をカスタムコマンドまたはカスタム関数に配置する時間を節約できます。


うーん。私はこれが好きです。私もそのための関数を書くことができるはずです。
Kevin

8

最初の質問については、次のようにします。

:s/a/b
&&

2つ目はトリッキーです。自動で行う方法はわかりませんが、次のように一致するたびにvimにプロンプ​​トを表示させることができます。

:s/a/b/gc

次に、最初のn個の一致に「いいえ」、他の一致に「はい」と応答します。


うーん、忘れていましたがc、それはまだ提案されている最良のソリューションかもしれません。私はまだ数える必要がありますが、検索文字列を含む置換で機能する最初のオプションだと思います。
Kevin

6
a a a a a
a a a a a
a a a a a
a a a a a
a a a a a
a a a a a
a a a a a

:3,6g/^/let i=0 | while i<3 | s/a/b/ | let i+=1 | endwhile

a a a a a
a a a a a
b b b a a
b b b a a
b b b a a
b b b a a
a a a a a

1
これは良いことですが、Gillesが指摘した問題(別の投稿で、削除されたように思われるため)に引き続き悩まされており、置換にパターンが含まれていない場合にのみ機能します。私はスクリプトのアイデアが好きですが。
Kevin

美しさ!
ビショップ

1

私はこれがうまくいくと思います、最初に交換してから2回繰り返します:

:s/a/b/
2@:
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.