메모장처럼 일반 검색 및 바꾸기?

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에서 리터럴 문자열을 검색하는 진정한 기능이 없기 때문에 어떤 방식 으로든 타협해야합니다. 당신을 위해 작동 할 수있는 당신이 만들 수있는 특별한 기능이 있습니다. 하지만이 솔루션은 구현이 매우 간단하고 사용이 매우 간단합니다.

[이 솔루션은 첫 번째 솔루션과 거의 공통점이 없기 때문에 첫 번째 답변을 편집하는 것이 아니라 두 번째 답변으로 게시하고 있습니다. 전체 답변을 수정하면 다른 회원이 추가 한 몇 가지 유용한 댓글이 더 이상 의미가 없습니다.]

나의 새로운 제안은 다음과 같다 ..

먼저 이것을 .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'를 입력하면 elephant라는 단어에서 'h'가 강조 표시 될 수 있습니다 (elephant가 파일 또는 현재 선택한 텍스트에 'h'가 처음 나타나는 경우).

두 번째 문자 ( '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')를 사용하여 다음 발생으로 이동하는 데 의존하기 때문에 이것은 중요합니다.

예를 들어, .php로 끝나는 호스트 'abcxyz.com'의 모든 URL을 편집하려면 다음과 같이 (일반 모드에서) 검색 할 수 있습니다.

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

(... 선행 '/'는 검색 패턴 입력을 시작하기 위해 일반 모드에서 입력하는 것입니다. '//'이 (가) 있는지 기억할 수 없기 때문에 URL에서 '//'를 '..'로 와일드 카드로 지정했습니다. 검색 작업에 영향을줍니다. 아름다움은 기억할 필요가 없다는 것입니다. 검색 패턴이 변경해야하는 모든 항목을 포착 할 수있을만큼 정확하고 변경하고 싶지 않은 패턴과 일치하지 않는 한, 저는 좋습니다. 토고)

Enter 키를 누르고 URL의 첫 번째 항목에 배치되면 원하는대로 해당 URL을 수동으로 변경합니다. 예를 들어 호스트 이름을 'abcxyz.com'에서 'a111b222.com'으로 변경하려면 다음을 입력하여 편집 할 수 있습니다.

'cfzhttp://a111b222'

.. 이것은 이것을 편집하는 여러 방법 중 하나 일뿐입니다. 명령 모드 편집이 아닌 일반 모드 편집인지 확인하십시오.

다음으로 다음 발생 ( 'n')으로 진행합니다.

마지막으로 여전히 일반 모드에서 변경해야한다고 생각하는 변경 횟수 를 초과 하는 정수를 입력 합니다. 정수는 정확할 필요는 없으며 변경할 변경 횟수보다 커야합니다. 얼마나 많은 변경이 필요한지 정말로 모른다면 100000000000을 사용할 수도 있습니다. 20 개만 변경할 경우 내 매크로는 20 번째 발생 후에 중지됩니다.)

큰 정수를 입력했으면 Enter 키를 누르지 말고 F8 키 (또는 매크로를 할당 한 키)를 누릅니다.

이렇게하면 첫 번째 발생에 대해 수동으로 수행 한 것과 똑같이 패턴의 모든 발생이 변경됩니다.

내 매핑에서 가정하는 한 가지 가정은 처음 F8 키를 누를 때 첫 번째 변경을 수행하려는 파일에 정확히 위치한다는 것입니다.

이전 편집 반복 연산자의 좋은 점은 특정 유형의 편집에만 국한되지 않는다는 것입니다. 한 글자, 한 단어, 줄의 끝, 줄의 시작, 전체 단락 등으로 변경할 수 있습니다.

다시 말하지만, 아이디어는 수동으로 한 번 변경하는 것입니다. 단어, 5 개 단어, 반 줄, 7 줄을 변경해도 상관 없습니다. 마지막 편집 반복 연산자가 이것을 기억합니다.

그런 다음 변경할 다음 항목을 검색하고 커서가 올바른 위치에 있는지 확인합니다 (예 : 전체 URL을 변경하는 경우 커서가 "http : //"가 아닌 "http : //"시작 부분에 있는지 확인합니다. URL 중간)을 누른 다음 10000F8을 누릅니다.

10,000 개 이상의 발생이있는 경우 정수를 더 크게 변경하십시오.

이것의 단점은 성능입니다. 그러나 그것은 정말 엄청난 수의 편집이있을 때만 문제가됩니다. (저에게 10,000 개 이상의 변경은 느리지 만 허용 할 수 있습니다. 100,000 개를 초과하면 시간이 오래 걸리고 : s로 되 돌리는 것이 좋습니다.하지만 마일리지는 다르다)

다른 사람들이 지적했듯이 또 다른 단점은 이스케이프를 제거했지만 와일드 카드를 제거하지 않았다는 것입니다. 그러나 set incsearchvimrc에 있으면 와일드 카드가 필요한 것을 찾는 것은 매우 쉽습니다 . 이 기능은 검색 패턴을 입력 할 때 일치하는 텍스트를 강조 표시합니다. 라이브 피드백이 아무 것도 강조 표시하지 않으면 패턴이 잘못되었음을 알 수 있습니다. 일반적으로 이스케이프해야하는 캐릭터 때문입니다. 문자를 '.'로 바꾸고 싶습니다. 포괄 자리 표시 자로 사용 (입력하는 것이 더 간단하다고 생각하기 때문에 이스케이프를 사용하는 것도 괜찮습니다)

husB Aug 24 2020 at 15:44

을 사용 cgn하고 ..

  • 먼저를 사용하여 '이전'문자열을 검색합니다 /.

  • 다음으로 cgn. 이것은 'old'의 다음 항목을 대체하고 삽입 모드로 전환합니다.

  • '새'대체 텍스트를 입력하고 Esc완료되면 누르십시오.

  • 다른 모든 'old'항목에 대해 [count]..

아이디어는 'new'대체 문자열을 good ol '삽입 모드로 입력하는 것이므로 특수 문자 이스케이프에 대해 걱정할 필요가 없습니다.

의 경우 [count]많은 수로 충분합니다. 또는 'old'의 발생 횟수를 :%sgn.

( '구'에 특수 문자에 관해서는, 내가 생각할 수있는 최선이다 /\V<old>. 당신은 아직 탈출해야합니다 \/하지만.)