Vim 검색은 현재 (프로젝트) 폴더의 모든 파일을 대체합니다


36

Vim에 대해 공개 질문 중 하나는 현재 프로젝트에서 검색 / 바꾸기를 수행 할 수있는 방법이 있는지 여부입니다 (다른 편집자로부터 상속 된이 개념을 사용하는 경우 나와 함께하십시오).

예를 들어, 프로젝트 파일에서 메소드 이름을 검색하고 해당 메소드 호출의 모든 인스턴스 이름을 바꾸고 싶다고 가정하십시오.

이것이 Sublime을 진행하는 방법입니다.

여기에 이미지 설명을 입력하십시오

Vim (또는 아마도 MacVim)에서 ack또는 같은 다른 프로그램에 의존하지 않고 sed어떻게 하시겠습니까?

답변:


35

이를 수행하는 몇 가지 방법이 있습니다.

내부 현재 디렉토리

프로젝트 트리에서 검색 / 바꾸기를 수행하려면 Vim의 argument list를 사용할 수 있습니다 .

Vim을 열고 :args명령을 사용 하여 인수 목록을 채우십시오. 여러 파일 이름이나 글롭을 전달할 수 있습니다.

예를 들어, :args **/*.rb현재 디렉토리에서 루비 파일을 재귀 적으로 검색합니다. 이것도로 Vim을 여는 것과 같습니다 vim **/*.rb. 쉘 find명령을 사용하여 다음을 실행하여 현재 디렉토리의 모든 파일 목록을 가져올 수도 있습니다 .

:args `find . -type f`

:args자체적 으로 실행하여 현재 인수 목록을 볼 수 있습니다 . 목록에서 파일을 추가하거나 삭제하려면 :argadd또는 :argdelete명령을 각각 사용할 수 있습니다 .

목록에 만족 :argdo하면 인수 목록의 모든 파일에 대해 명령을 실행하는 Vim의 강력한 명령을 사용할 수 있습니다 .:argdo %s/search/replace/g

다음은 검색에 대한 몇 가지 팁입니다 (일부 의견을 기반으로 함).

  1. "foo_bar"가 아닌 "foo"를 검색하려면 단어 경계를 사용하십시오. 다음 \<\>같이 검색 패턴 주위에 및 구문을 사용하십시오 .:argdo %s/\<search\>/foobar/g
  2. /cVim이 검색어를 바꾸기 전에 확인을 요청하도록 하려면 검색 플래그를 사용하십시오 .
  3. /e"패턴을 찾을 수 없음"오류를 건너 뛰려면 검색 플래그를 사용하십시오 .
  4. 검색을 수행 한 후 파일을 저장하도록 선택할 수도 있습니다 :argdo %s/search/replace/g | update.. 여기에서는 :update파일이 변경된 경우에만 파일을 저장하기 때문에 사용됩니다.

열린 버퍼

버퍼가 이미 열려있는 경우 검색 / 바꾸기를하려는 경우 :bufdo버퍼리스트 ( :ls)의 모든 파일에 대해 명령을 실행하는을 사용할 수 있습니다 .

이 명령은 다음과 매우 유사합니다 :argdo. :bufdo %s/search/replace/g

유사 :argdo하고 :bufdo, 존재 :windo하고 :tabdo각각 창과 탭에 해당 법. 그것들은 덜 자주 사용되지만 여전히 유용합니다.


4
/c대체를 확인 하기 위해 플래그 를 사용하는 것이 좋습니다 .
romainl

3
또한 단어 경계를 사용하는 것이 좋습니다 것입니다 \<\>주위에 search부분적인 단어 교체를 방지 할 수 있습니다.
tommcdo

1
다른 의견으로는 vim의 작업 디렉토리는 기본적으로 현재 파일의 디렉토리가 아니라 vim을 시작한 위치입니다. 를 사용하여 작업 디렉토리를 현재 파일로 설정할 수 있습니다 :cd %:p:h. 다른 작업 디렉토리 옵션은 vim.wikia.com/wiki/Set_working_directory_to_the_current_file에 나열되어 있습니다 .
studgeek

27

다음과 같은 간단한 프로젝트 구조가 있다고 가정 해 봅시다.

여기에 이미지 설명을 입력하십시오

greeting.txt는 다음과 같습니다

여기에 이미지 설명을 입력하십시오

info / age.txt는 다음과 같습니다

여기에 이미지 설명을 입력하십시오

Sam의 모든 발생을 Bob으로 바꾸고 싶다고 가정 해 봅시다. 우리가 할 일은 다음과 같습니다.

  1. 작업 디렉토리 설정

    Vim의 현재 작업 디렉토리가 프로젝트의 루트인지 확인하십시오 (여기에서 수행하는 방법은 표시하지 않음).

  2. 'Sam'이 포함 된 파일 찾기

    Vim의 vimgrep 명령을 사용하여 프로젝트 내에서 Sam의 모든 발생을 검색하십시오 (참고 : **/*모든 파일에서 반복적으로 검색)

    :vimgrep /Sam/gj **/*
    

    이렇게하면 Quickfix 목록이 Sam의 모든 인스턴스로 채워집니다. 빠른 수정 사항 목록을 보려면 Vim 명령을 사용할 수 있습니다:copen 여기에 이미지 설명을 입력하십시오

  3. 'Sam'이 포함 된 모든 파일 내에서 대체

    이제 빠른 수정 사항 목록의 모든 파일에서 Vim의 대체 명령을 실행하려고합니다. :cfdo {cmd}빠른 수정 사항 목록의 각 파일에서 {cmd}를 실행 하는 명령을 사용하여 이를 수행 할 수 있습니다 . 우리가 사용하고자하는 특정 {cmd}는 짧 substitute거나 s짧습니다. 전체 라인은 다음과 같습니다.

    :cfdo %s/Sam/Bob/g
    

    원하는 경우 c 플래그를 추가하여 모든 교체를 확인할 수 있습니다.

    :cfdo %s/Sam/Bob/gc
    
  4. 모든 파일을 저장

    :cfdo update
    

2
나는 이것을 더 좋아한다. 간단하고 Ack (또는 QuickFix 창을 채우는 모든 플러그인)과 함께 작동합니다.
Zuhaib

1
이것은 훌륭한 답변입니다
Peoplee

2
"마지막 변경 이후로 쓰기"점점되지 않았다, 이렇게 cfdo %s/Sam/Bob/g | update고정이 나를 위해
hakunin

@hakunin 아직 설정 하지 않은 경우 hidden옵션을 설정하는 것이 좋습니다 :set hidden.
Niko Bellic

3

VIM 솔루션은 아니지만 VI / VIM을 사용하는 경우 CLI 솔루션을 사용하는 것이 더 쉬울 수 있습니다. 현재 디렉토리의 모든 파일을 변경하려면 다음 perl과 같은 상황 에서 사용 된 대로 사용 하십시오.

$ perl -pi -e 's/foo/bar/g' *

하위 디렉토리 에서도이 작업을 수행 해야하는 경우 일반적으로 다음과 페어링 perl됩니다 find.

$ find . -name '*' -print0 | xargs -0 perl -pi -e 's/foo/bar/g'

이에 대한 좋은 점은 목록을 특정 파일 형식으로 쉽게 세분화 할 수 있다는 것입니다. 예를 들어, 파이썬 파일로 제한하려면 :

$ perl -pi -e 's/foo/bar/g' *.py
$ find . -name '*.py' -print0 | xargs -0 perl -pi -e 's/foo/bar/g'

1

구를 다른 구로 바꾸려면 Vim Ex 모드를 사용할 수 있습니다.

예를 들어 (의 ex별칭입니다 vim -E) :

$ ex -s +'bufdo!%s/foo/bar/g' -cxa *.*

bash / zsh에서 재귀 적으로 ( globstar예 :) shopt -s globstar:

$ ex -s +'bufdo!%s/foo/bar/g' -cxa **/*.*
$ ex -s +'n **/*.*' +'bufdo!%s/foo/bar/g' -cxa

재귀 적으로 ( find파일과 같은 숨겨진 파일 사용 및 무시 .git) :

$ find . -type f -not -path '*/\.*' -exec ex -s +'bufdo!%s/foo/bar/g' -cxa {} "+"

참고 : :bufdo명령은 POSIX 가 아닙니다 .

참고 : 구문 -not -path '*/\.*'은 숨겨진 파일 (예 :)을 무시하는 데 사용됩니다 .git.



0

다음은 쉘 사용하는 명령입니다 findex(없는 편집기 사용이:bufdo ) :

find . -name '*.rb' -exec ex +'%s/foo/bar/ge' -V1 -scwq! {} ';'

이 의지 편집은 모두-배치 *.rb현재 폴더 (재귀 적으로)에있는 파일과 교체 foo와 함께 bar.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.