Vim : s는 줄에서 첫 번째 N <g 발생을 바꿉니다.


13

vim에서, 때때로 라인에서 처음 몇 번의 일치 항목을 교체 할 기회가 있지만 모든 것을 좋아하지 g는 않습니다 . 예 :

a a a a a

b b b a a

나는을 사용할 수 있다는 것을 알고 :s/a/b/[enter]:[up][enter]:[up][enter]있지만 세 번의 반복에서 충분히 지루합니다. 잠재적 인 10 + 대체가있는 줄이 있습니다.
난 노력 했어:

  • :s/a/b/3g: vim은 후행 문자에 대해 불평했습니다.
  • :s/a/b/3:이 행과 다음 두 행에서 첫 번째 항목을 변경합니다.
  • 3:s/a/b: 이전과 동일합니다.
  • :s/a/b/g3:이 행과 다음 두 행의 모든 ​​발생을 변경합니다.
  • :3s/a/b: 3 행에서 첫 번째 항목을 변경합니다.
  • :/a/,3/a/s/a/b: 파일에 a포함 a된 다음 행 과 세 번째 행 사이의 각 행에서 첫 번째 발생을 변경 합니다 (필요한 경우 반전하도록 프롬프트).
  • :/a/,/\([^a]*a\)\{3\}/s/a/b/: 이것과 다음 행 사이의 각 줄에서 첫 번째 항목을 3 a초로 변경합니다 (여러 문자 검색으로 쉽게 확장 할 수 없었습니다).

그리고 다양한 다른 주소 지정 패턴 중 어느 것도 효과가 없었습니다. 나는 :s이 문제에 대한 답을 찾으려고하는 명령 에 대해 상당한 금액을 배웠지 만 여전히 해결하지 못했습니다.

이 작업을 수행하는 방법을 아는 사람이 있습니까?

(특정 범위에 대한 보너스 포인트, 예 : 두 번째에서 네 번째 발생)


2
vim에서는 그렇게 할 수 없다고 확신하지만 덜 지루하게 만들려면 "n"과 "."에 대해 알고 있습니까? 비주얼 모드? 즉, / pattern /을 사용하여 변경할 것을 찾거나 "cw"등을 사용하여 변경하거나 "n"(n 만 사용하고 따옴표 없음)을 사용하여 다음 패턴을 찾고 ""를 누르십시오. (마침표 만, 따옴표 없음) 마지막 편집을 수행합니다.
Bruce Ediger

@BruceEdiger 나에 대해 알고 않았다 n그리고 .내가 여기를 사용하여 생각하지 않았지만,. 확실히 향상되었습니다. 감사합니다.
Kevin

s/a/=something/트릭을 수행해야합니다 ( :help sub-replace-=). 나는 Vim something에서 방망이 를 쓸만큼 유창하지 않다 .
Gilles 'SO- 악한 중지'12

참고 : :[up][enter]로 대체 할 수 있습니다 . &이상적이지는 않지만 적어도 덜 고통 스럽습니다.
Kowh

답변:


10

:s/pattern/replacement/gc Samus_아이디어를 바탕으로 (대체 문자열 내에 패턴이 포함되어있을 때 패턴이 올바로 작동 할 수있는 가장 간단한 방법 인 것 같습니다), 두 번째에서 네 번째 항목을 한 줄로 바꿉니다 .

:call feedkeys("nyyyq") | s/pat/string/gc

feedkeys()입력 문자열을 키보드 입력 대기열에 넣는 함수입니다. 요점은 카운트를 미리 계산하여 카운트를 잃거나 중단되는 것에 대해 걱정할 필요가 없다는 것입니다.

보다 일반적인 경우에있어서의 교체 제 M을 통해 제 N에 대한 단일 행에 발생 N의 매우 큰 이상인 M :

:call feedkeys(repeat("n", M-1) . repeat("y", N-M+1) . "q") | s/pat/string/gc

MN 을 원하는 값으로 바꿉니다 ( vim직접 수행하고 싶지 않은 경우 사소한 정신 산술을 할 수도 있습니다). 참고 .VimL의 문자열 연결 연산자입니다. 분명히 이것은 큰 M에 대한 키 입력 만 저장 합니다. 이 기능을 자주 사용하는 경우, 입력하기가 다소 쉽기 때문에 위의 명령을 사용자 정의 명령이나 일종의 함수에 넣는 시간을 절약 할 수 있습니다.


흠. 난이게 좋아. 나는 그것을 위해 함수를 작성할 수 있어야한다.
Kevin

8

첫 번째 질문은 다음과 같습니다.

:s/a/b
&&

두 번째는 까다 롭습니다. 자동으로 수행하는 방법을 모르지만 다음과 같이 각 경기에서 vim 프롬프트를 표시 할 수 있습니다.

:s/a/b/gc

그런 다음 첫 n 개의 일치 항목에 "아니오"라고 답하고 다른 n 개의 일치 항목에는 "예"라고 대답합니다.


흠, 나는 잊어 버렸다 c. 아직 제안 된 최상의 솔루션 일 수있다. 나는 여전히 계산해야하지만 검색 문자열이 포함 된 대체물과 함께 작동하는 첫 번째 옵션이라고 생각합니다.
케빈

6
a a a a a
a a a a a
a a a a a
a a a a a
a a a a a
a a a a a
a a a a a

:3,6g/^/let i=0 | while i<3 | s/a/b/ | let i+=1 | endwhile

a a a a a
a a a a a
b b b a a
b b b a a
b b b a a
b b b a a
a a a a a

1
이것은 좋지만 여전히 교체가 패턴을 포함하지 않는 경우에만 작동한다는 Gilles가 지적한 문제 (다른 게시물에서 삭제 된 것으로 보입니다)로 여전히 고통 받고 있습니다. 스크립팅 아이디어가 마음에 들지만.
케빈

아름다움의 것!
주교

1

이것이 효과가 있다고 생각하고 먼저 교체 한 다음 2 번 반복하십시오.

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