メモ帳のように簡単に検索して置き換えますか?

Aug 21 2020

私はsubstituteコマンドとそのexコマンドとしての使用法を知っています:%s/<old>/<new>/g

ただし<new>、非常に複雑な文字列が含まれている場合、たとえば、% [ ] : / \などのような文字がたくさんある複雑なURLの場合、文字はコマンドの一部になり始め(特に/または:)、エスケープシーケンスの使用を開始する必要があります。\

オフの方法があり、すべてのエスケープの必要性と、すべての解釈は、私が交換できるようにすることを、<old><new>たとえ<old><new>を含む任意のASCII文字を、持っている/ : [ ] % # $ ( )など?

現在、私はこれを行うためにメモ帳に頼っていますが、VIMにとどまることができることを願っています。

回答

1 eyalkarni Aug 22 2020 at 05:30

パターンにが含まれていないと仮定すると\、これは機能します。

:%s/\Vpattern/\='string'

すべての場合において、pattern&replace文字列が変数にある場合、これは機能します。

let pattern='<old>'
let str='<new>'
:exec "s/\\V" . escape(escape( pattern, '\'),'/') . "/\\=str"

もちろん、input()やコマンド引数などのさまざまなメソッドを使用して変数を設定できます。

PaperclipBob Aug 22 2020 at 08:14

私の最初の答えについてのコメントを読んだ後、私はおそらく私の最初の提案とは大きく異なる非常に単純な解決策があることに気付きました。この新しい提案では、時折「。」を使用する必要があります。特殊文字を照合するための代用としてですが、vimでリテラル文字列を検索する真の機能がないため、何らかの方法で妥協する必要があります。あなたがあなたのために働くかもしれないあなたが作ることができる特別な機能があります。しかし、このソリューションは実装が非常に簡単で、使用も非常に簡単だと思います。

[このソリューションは私の最初のソリューションとほとんど共通点がないため、最初の回答を編集するのではなく、2番目の回答として投稿します。回答全体を編集すると、他のメンバーが追加したいくつかの役立つコメントは意味がなくなります]

私の新しい提案は次のとおりです。

まず、これを.vimrcに配置します...

set incsearch

から:h incsearch...

While typing a search command, show where the pattern, as it was typed
so far, matches. The matched string is highlighted. If the pattern
is invalid or not found, nothing is shown. 

[以下の例では、検索パターンが「:global」または「:substitute」コマンドの一部であると想定しています]

URLを照合する場合は、と入力し始めますhttp:。入力すると、ファイルまたは選択したテキストで次に一致する可能性のあるものが画面に表示され、強調表示されます。最初の文字「h」を入力すると、象という単語の「h」が強調表示される場合があります(象のファイルまたは現在選択されているテキストで「h」が最初に出現する場合)

2番目の文字(「t」)を入力すると、検索文字列は「ht」になり、強調表示されたフォーカスは「ht」の最初の一致に移動します。これはおそらくURLと一致します(「ht」を含む単語は多くありません)。探しているURLではない可能性があります。しかし、検索パターンの入力は完了していません。

だから、あなたはタイプし続けます。別の「t」(「htt」)、「p」(「http」)、およびコロン(「http:」)。ここまでは順調ですね。最初のURLは引き続き画面上で強調表示されます。それでも必要なURLではない可能性がありますが、少なくともこれまでのパターン(http:)が機能していることはわかっています。

ただし、「/」と入力するとすぐに、強調表示によって入力内容が追跡されなくなることがわかります。'http:/'の検索に問題があります。'/'をエスケープする必要があることを忘れているかもしれません。

しかし、何をエスケープする必要があるかを覚えておく必要はありません!!!

ライブフィードバックは、URLと一致しなくなると、「http:」に「/」を追加しても何にも一致しないことをすぐに通知します。

'/'をエスケープする必要があります。ただし、「/」をエスケープする代わりに、単一の「。」を入力することをお勧めします。'\ /'よりも入力が簡単だからです。ただし、「。」と入力することはできます。または '\ /'

このアプローチの欠点は、(1)エスケープまたは「。」の必要性を完全に排除しないことです。(2)検索パターンを入力している間、画面の位置がファイル内を移動する可能性があります。

私の経験では、どちらも私を悩ませません。そうでなければ見つけるかもしれません。

(1)の場合、エスケープする必要があるものを入力するとすぐにわかります。これにより、検索文字列を作成する際の当て推量がすべて排除されます。私はそれが非常に単純な妥協であり、非常に扱いやすいと思います。

(2)の場合、検索文字列を入力しているときに、ファイル内の元の位置を確認する必要はほとんどありません。実際、次のパターン一致に向けたライブの動き(および検索パターンが有効であることを確認するために提供されるフィードバック)は、単に文字列を入力して一致させたいものと一致することを期待するよりもはるかに望ましい(IMO)。ただし、元の位置を確認する必要が続く場合は、単純な水平分割画面でうまくいくはずです。

PaperclipBob Aug 21 2020 at 23:56

私の.vimrcにはこれらの行があります...

set incsearch
let @o = ".nzz"
map <F8> @o

これらのコマンドを使用すると、特殊文字をエスケープすることを心配することなく、あらゆる種類の編集を行うことができます。また、複数行の編集を簡単に行うことができます。

これらのコマンドが.vimrcに含まれると、手順は次のようになります。

まず、変更したいすべてのオカレンスに一致するパターンを検索する必要あります。私の解決策は、find-next演算子( 'n')を使用して次のオカレンスに移動することに依存しているため、これは重要です。

たとえば、ホスト 'abcxyz.com'のすべてのURLを編集する場合、たとえば.phpで終わる場合は、次のように(通常モードから)検索できます。

/http:..abcxyz.com.*.php

(...先頭の「/」は、検索パターンの入力を開始するために通常モードで入力するものです。「//」が「//」になるかどうか思い出せないため、URLの「//」を「..」でワイルドカード化しました。検索操作に影響を与えます。美しさは、覚えておく必要はありません。検索パターンが、変更する必要のあるすべてのオカレンスをキャッチするのに十分正確であり、変更したくないパターンと一致しない限り、私は良いです。トーゴ)

Enterキーを押して、URLの最初のオカレンスに配置されたら、必要に応じてそのURLを手動で変更します。たとえば、ホスト名を「abcxyz.com」から「a111b222.com」に変更する場合は、「...」と入力して編集できます。

'cfzhttp://a111b222'

..これはこれを編集する多くの方法の1つにすぎません。コマンドモードの編集ではなく、通常モードの編集であることを確認してください。

次に、次のオカレンス( 'n')に進みます。

最後に、通常モードのままで、必要と思われる変更の数を超える整数を入力します。整数は正確である必要はなく、変更の数よりも大きい必要があります。変更がいくつ必要か本当にわからない場合は、100000000000を使用することもできます。変更が20回しかない場合、マクロは20回目以降に停止します)。

大きな整数を入力したら、Enterキーを押さないでください。F8キー(またはマクロを割り当てたキー)を押してください。

これにより、最初の出現に対して手動で行ったのとまったく同じように、パターンのすべての出現が変更されます。

私のマッピングが想定している1つの前提は、F8を初めて押すと、ファイル内で最初の変更を行う場所に正確に配置されるということです。

前の繰り返し編集演算子の良いところは、特定の種類の編集に制限されていないことです。1文字、1単語、行末、行頭、段落全体などを変更できます。

したがって、繰り返しになりますが、手動で変更を1回行うという考え方です。単語、5単語、半行、7行を変更しても問題ありません... repeat-last-editオペレーターはこれを覚えています。

次に、変更する次のオカレンスを検索し、カーソルが適切な場所にあることを確認します(たとえば、URL全体を変更する場合は、カーソルが「http://」の先頭ではなく「http://」の先頭にあることを確認します。 URLの中央)を押してから、10000F8を押します。

10,000回を超えるオカレンスがある場合は、整数を大きく変更します。

これの欠点はパフォーマンスです。しかし、それは本当に膨大な数の編集を行う場合にのみ問題になります(私にとって、10,000を超える変更は遅いが許容できる場合があります。100,000を超えると非常に長い時間がかかる可能性があり、:sに戻すことをお勧めします-しかし、マイレージは異なります)

他の人が指摘しているように、もう1つの欠点は、エスケープを廃止したにもかかわらず、ワイルドカードを廃止していないことです。しかしset incsearch、vimrcにある場合、ワイルドカードにする必要があるものを見つけるのは非常に簡単です。この機能は、検索パターンを入力するときに一致したテキストを強調表示します。ライブフィードバックで何かが強調表示されなくなると、パターンが間違っていることがわかります。通常は、エスケープする必要のあるキャラクターが原因です。文字を「。」に置き換えることを好みます。キャッチオールプレースホルダーとして(入力が簡単だと思ったからですが、エスケープを使用しても問題ありません)

husB Aug 24 2020 at 15:44

を使用しcgn、で繰り返し.ます。

  • まず、/。で「古い」文字列を検索します。

  • 次に、を押しcgnます。これにより、次に出現する「old」が置き換えられ、挿入モードになります。

  • 「新しい」置換テキストを入力し、Esc完了したらヒットします。

  • 'old'の他のすべての出現について、を使用して繰り返し[count].ます。

アイデアは、「新しい」置換文字列を「古き良き」挿入モードで入力することです。これにより、特殊文字のエスケープについて心配する必要がなくなります。

の場合[count]、任意の数で十分です。または、「old」の出現回数を。で調べます:%sgn

(「古い」の特殊文字については、私が考えることができる最善の方法です/\V<old>。ただし、それでもエスケープする必要が\あり/ます。)