Vimで選択したテキストを検索して置換する


109

テキストがあるとしましょう。ビジュアルモードに入り、テキストを選択します。強調表示されたテキストをすばやく検索して別のテキストに置き換えるにはどうすればよいですか?

回答:


135

以下を実行するか、あなたの中に入れてみてください .vimrc

vnoremap <C-r> "hy:%s/<C-r>h//gc<left><left><left>

ビジュアルモードでctrl+ rを押すと、置換するテキストを入力するように求められます。を押してenter、に同意yまたは拒否する各変更を確認しnます。

このコマンドはレジスターをオーバーライドするhため、使用しないレジスターを(h上記のコマンドで別の小文字に変更することにより)選択できます。


13
cin を省略するとgc、バッファー全体で一度に置換が行われます。間違えて元に戻したい場合はu、コマンドモードで入力してください。私はこの方法が好きです(置換のそれぞれを確認するよりもcモディファイアで発生します)。
Niloct 2011年

3
vmap * y:let @/ = @"<CR>選択された部分が強調表示されます。
kev

8
の目標は<left><left><left>何ですか?
aymericbeaumet 2013

7
@aymericbeaumetを使用して、2つのスラッシュの間にカーソルを置くと、置換する単語を簡単に入力できます。
mcabrams 14

5
あなたは取り外しについてNiloctの提案@取る場合注ことcからgc、あなたはまたの1削除する必要があります<left>行の末尾からのを。
Nathan Friend 14

36

(hレジスタを上書きせずに)視覚的に強調表示されたテキストを検索し、端末依存の+レジスタを使用せずに、このすばやく簡単なマッピング検索を実行します。

" search for visually hightlighted text
vnoremap <c-f> y<ESC>/<c-r>"<CR>   

ctrl-fが気に入らない場合は、好みに変更してください

テキストが強調表示されたら、s次のように入力するだけでいつでも変更を行うことができます。

%s//<your-replacement-string>

... sコマンドの空の検索は、最後に検索された文字列を使用するためです。


これをvim構成で使用する場合、control+f常に次の文字と視覚的に選択した文字を選択します。何か案は?
ロバートマークブラム

%s//<your-replacement-string>のようなものを強調するために動作しないようです/tmp/file。それはちょうどなる<your-replacement-string>/tmp/file
naisanza

28

これも機能します(少なくとも1行の選択/特殊文字を含まない選択の場合)

  • ビジュアルモードでテキストを選択する
  • テキストをヤンクする y
  • :s/<C-r>0/

0 ヤンクレジスタです。

他の人が述べたように、これを行うにはより速い方法がありますが、Vim(私のように)を学び始めたばかりの場合、これは「一般的な」方法の1つです。

//編集:タブや改行などの/文字または選択範囲に文字がある場合、「登録」アプローチが失敗することに気づきました(:sコマンドを機能させるために、これらの文字を手動で処理する必要があります)。

ここに画像の説明を入力してください


2
とても簡単です。なんてこと、ウィキでカバーされていないのか。さあ…答えてくれてありがとう!
Benyamin Limanto

2
これは、Vimの学習曲線の初期段階にまだいる私たちにとって理想的な答えです。私はカスタマイズが強みであることを知っていますが、複雑なスクリプトをvimrcにコピーアンドペーストして、これほど単純な問題でどのように組み合わされるかを理解したくありません。この答えは、ctrl-Rがレジスタをダンプすることを教えてくれました。これは、他のコンテキストで覚えておくと便利です。
ニベック

26

ビジュアルセレクションに特殊文字が含まれていない限り、受け入れられた回答は適切に機能します。2つのスクリプト(Jeremy Cantrellの投稿とPeter Oddingのスクリプト)を組み合わせて、特殊な正規表現文字が含まれている場合でも、検索したい文字列を視覚的に選択できるコマンドを作成しました。

" Escape special characters in a string for exact matching.
" This is useful to copying strings from the file to the search tool
" Based on this - http://peterodding.com/code/vim/profile/autoload/xolox/escape.vim
function! EscapeString (string)
  let string=a:string
  " Escape regex characters
  let string = escape(string, '^$.*\/~[]')
  " Escape the line endings
  let string = substitute(string, '\n', '\\n', 'g')
  return string
endfunction

" Get the current visual block for search and replaces
" This function passed the visual block through a string escape function
" Based on this - /programming/676600/vim-replace-selected-text/677918#677918
function! GetVisual() range
  " Save the current register and clipboard
  let reg_save = getreg('"')
  let regtype_save = getregtype('"')
  let cb_save = &clipboard
  set clipboard&

  " Put the current visual selection in the " register
  normal! ""gvy
  let selection = getreg('"')

  " Put the saved registers and clipboards back
  call setreg('"', reg_save, regtype_save)
  let &clipboard = cb_save

  "Escape any special characters in the selection
  let escaped_selection = EscapeString(selection)

  return escaped_selection
endfunction

" Start the find and replace command across the entire file
vmap <leader>z <Esc>:%s/<c-r>=GetVisual()<cr>/

誰にとっても便利な場合は、これをvimrcに含めました。


2
解決策に感謝し、複数の提案を組み合わせて、私は次のようになりました:(vmap <C-r> <Esc>:%s/<c-r>=GetVisual()<cr>//g<left><left>ファイルのすべてを置き換えるだけです)
Peter Butkovic 2013年

13

Vim 7.4以降gnでは、現在の検索パターンに一致するテキストの領域を選択するモーションを使用できます。

を使用cgnして現在選択されている一致のテキストを変更した後(またはdgn削除した後)、通常モードでは.、コマンドを繰り返して次の一致を操作できます。

この機能を示すVimcastのエピソードがあります。


3
これは素晴らしい答えです!
mauriciojost

これも素晴らしいです。colemikの答えはさておき。偉大な者!
Benyamin Limanto

うわー、それはあなたが深い解決策を見つけるために深くブラウジングするときにあなたが見つけるそれらの秘密のようなものです、ありがとう!
vdegenne

8

Mykola Golubyev、ヒントをありがとう!以下では、「+」レジスタを使用します(端末によって異なります)。ハイライトされたテキストがすでに含まれているため、「h」レジスタを使用する必要はありません。

vnoremap <C-r> <Esc>:%s/<C-r>+//gc<left><left><left>

CentOS 5.x上のVIM 7.0に+レジスタがないようです。これは標準機能ですか?
dotancohen 2012

3
私はPuttyを介してCentOSマシンにアクセスし、グーグルで+がクリップボードレジスタであることを確認します。パテはそれをサポートしていないようです!したがって、この回答は実際には端末によって異なります。
dotancohen 2012

こんにちは、私はあなたのコマンドを試しましたが、選択されたテキストだけでなく、すべてのファイル全体で指定されたテキストの出現を置き換えるように求めています
solalito

7

http://vim.wikia.com/wiki/Search_and_replace_in_a_visual_selectionから:

テキストが視覚的に選択されているときに、:を押してコマンドを入力します。コマンドラインは自動的に範囲を入力します:

:'<,'>

s / red / green / gなどのコマンドを入力して、最後のビジュアル選択のすべての行で各赤を緑に置き換えることができます。コマンドは次のように表示されます。

:'<,'>s/red/green/g

以前に選択したブロックに対してExコマンドを繰り返すには、:履歴を使用します。つまり、:を押してから、前のコマンドを編集します。


4
はい、これは選択した領域で赤を緑置き換えます-非常に便利ですが、操作者が要求したものではありません。
ErichBSchulz 2013

@ErichBSchulz選択したすべての行で実際に実行されます。したがって、行の一部だけが選択されている場合でも、行全体に適用されます。
カリー

1
多分それはOPの質問には答えませんが、これは私の検索「vim search and replace with visual selection」に正確に答えます。この場合、検索と置換を視覚的な選択のみに制限したいため、この質問が表示されます
icc97

5

私はこれを私のvimrcに持っています:

function! GetVisual() range
    let reg_save = getreg('"')
    let regtype_save = getregtype('"')
    let cb_save = &clipboard
    set clipboard&
    normal! ""gvy
    let selection = getreg('"')
    call setreg('"', reg_save, regtype_save)
    let &clipboard = cb_save
    return selection
endfunction

vmap <leader>z :%s/<c-r>=GetVisual()<cr>/

これは、視覚的な選択を取得し、それを使用して置換コマンドを開始します。

編集:これは複数行のビジュアル選択では機能しないことを指摘しておきます。GetVisual()はそれを返すことに問題はありませんが、コマンドラインに適切に配置する方法がわかりません。誰か私がこれを行う方法についてのヒントがあれば、コメントしてください。


2

箱から出してこれを行うことはできないと思います。しかし、多くの人がこの機能を気に入っているので、マクロなどがたくさんあります(自分で追加しました)。たとえば、ここに追加できます。を押し*て、視覚的に選択されたテキストで次の一致を検索します。


2

他の回答も良いですが、特殊文字をエスケープしません。@brian kennedy の答えはエスケープする方法を示していますが、多くのコードが必要です。たとえばURLの場合、エスケープは必須です。そうしないと、「:」で検索が停止します。

vim.fandom.com/wiki/Search_for_visually_selected_textに記述されているように、ワンライナーを使用して一部の文字を検索およびエスケープできます。あなたはあなたが望む文字をエスケープすることができます、私はエスケープすることを選びました/\: :

vnoremap // y/\V<C-R>=escape(@",'/\:')<CR><CR>

このマップでは//、ビジュアルモードでを押して、バッファー全体で現在選択されているテキストを検索する必要があります。


1

これの私のお気に入りのショートバージョンは

vnoremap s / y:s / "/

次に、選択を強調表示し、s /を押すだけで、その置換コマンドを開始できます。


"リテラルとして扱われ、私にはうまくいきませんでした。<c-r>"でも働いた
Josh Bodah

1

コメントする担当者がいないので、別の回答を追加します...

vnoremap <C-r> "0y<Esc>:%s/<C-r>0//g<left><left>

@dmdと@dotancohen:これは、使い果たさずに機能し"h(明示的に0を使用します。これはとにかく最後のヤンクポジションです)、パテssh-> mint(lmde);で動作します。セントについて知らない。また、@ Niloctおよび@Nathan Friendのコメントを使用して確認を削除します。


1

例1.選択を星で囲み、カーソルを選択の先頭に置きます。

:%s,\%#\%V\_.*\%V/,**&**,c 

例2.選択したテキストをbase64でパイプ処理します。

:%s!\%#\%V\_.*\%V!\=system("base64 -w 0",@")!c

説明LHS:

\%# matches cursor 
\%V matches inside the selection only
\_. matches any character.
\_.* matches beginning to end of selection.

説明RHS:

\=expr()  Replace match with result of expr() for each substitution.

0

そもそも単語を入力し直さなくても、Vimに単語を置き換える組み込みの方法があることを望んでいました。ありますが、単語境界文字までのテキストに対してのみ機能します。

単語の上にマウスを置いたら、*または#を押して単語を強調表示し、その単語の次/前の場所にジャンプします(ファイル内の場所を変更したくない場合は、反対のキーを押して場所に戻りますあなたはちょうどでした)。

それから単にタイプしてください:

%s//<your-replacement-string>

他の人の答えで述べたように%s、スラッシュの間に空白のエントリを受け取った場合は、以前に検索された単語を使用します。*またはを押すと#、カーソルの下の単語が検索され、最後に検索された単語になります。

結局のところ、これを実行するのは6回または7回のキーストローク+置換ワードの長さだけであり、マクロの編集やの編集は必要ありません.vimrc

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