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

3
vmap * y:let @/ = @"<CR>선택됨이 강조 표시됩니다.
kev

8
의 목표는 <left><left><left>무엇입니까?
aymericbeaumet 2013-07-04

7
@aymericbeaumet을 사용하여 두 슬래시 사이에 커서를 가져 오면 대체 단어를 쉽게 입력 할 수 있습니다.
mcabrams

5
cfrom 제거에 대한 @Niloct의 제안을 받아들이 면 줄 끝에서의 gc중 하나도 제거해야합니다 <left>.
Nathan Friend

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항상 시각적으로 선택한 것뿐만 아니라 바로 다음 캐릭터를 선택합니다. 어떤 아이디어?
Robert Mark Bram

%s//<your-replacement-string>같은 것을 강조하는 데 작동하지 않는 것 같습니다 /tmp/file. 그냥이된다<your-replacement-string>/tmp/file
naisanza

28

이것은 또한 작동합니다 (적어도 한 줄의 선택 / 특수 문자가 포함되지 않은 선택)

  • 시각 모드에서 텍스트 선택
  • 텍스트를 잡아 당기다 y
  • :s/<C-r>0/

0 yank 레지스터입니다.

다른 사람들이 언급했듯이이 작업을 수행하는 더 빠른 방법이 있지만, 나처럼 Vim을 배우기 시작했다면 이것이 '일반적인'방법 중 하나입니다.

// 편집 : 탭이나 줄 바꿈 또는 /문자 와 같은 문자가 선택 항목에 있으면 '등록'방식이 실패한다는 것을 방금 깨달았습니다 ( :s명령이 작동 하려면 이러한 문자를 수동으로 처리 해야합니다).

여기에 이미지 설명 입력


2
아주 간단합니다. 오 이런, 왜 위키에서 다루지 않습니까. 어서 ... 대답 해주셔서 감사합니다!
Benyamin Limanto

2
이것은 Vim 학습 곡선의 초기 단계에있는 우리에게 이상적인 답변입니다. 커스터마이징이 강점이라는 것을 알고 있지만 복잡한 스크립트를 내 vimrc에 복사하여 붙여넣고 이처럼 간단한 문제를 해결하는 방법을 알아보고 싶지는 않습니다. 이 대답은 ctrl-R이 레지스터를 덤프하므로 다른 컨텍스트에서 기억하기 쉽습니다.
nivek

26

시각적 선택에 특수 문자가 없으면 허용되는 대답은 훌륭하게 작동합니다. 두 개의 스크립트 ( 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>(다만 모든 파일에 대체)
피터 Butkovic

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

안녕, 그냥 선택한 텍스트를 나는 당신의 명령을 시도했지만 모두에 걸쳐 파일을 지정된 텍스트의 발행 수를 대체하는 저를 요구하고있다, 그리고
solalito

7

에서 http://vim.wikia.com/wiki/Search_and_replace_in_a_visual_selection :

텍스트가 시각적으로 선택되면 :을 눌러 명령을 입력합니다. 명령 줄은 자동으로 범위를 입력합니다.

:'<,'>

s / red / green / g와 같은 명령을 입력하여 마지막 시각적 선택의 모든 줄에서 각 빨간색을 녹색으로 바꿀 수 있습니다. 명령은 다음과 같이 나타납니다.

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

이전에 선택한 블록에 대해 Ex 명령을 반복하려면 : history를 사용하십시오. 즉,을 누른 다음을 누른 다음 이전 명령을 편집합니다.


4
예 이것은 선택된 영역에서 빨간색을 녹색 으로 대체합니다. 매우 유용하지만 작전에서 요청한 내용은 아닙니다.
ErichBSchulz 2013

@ErichBSchulz 실제로 선택한 모든 줄에서 수행합니다. 따라서 라인의 일부만 선택하더라도 전체 라인에 적용됩니다.
Cully

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>"하지만 일
조쉬 Bodah

1

댓글을 달 담당자가 없어서 또 다른 답변을 추가하겠습니다.

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

@dmd 및 @dotancohen : 이것은 사용하지 않고 저에게 효과적이며 "h(명시 적으로 마지막 yank 위치 인 0을 사용함) putty 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.