“x”로 시작하여 중복 된“x”를“y”로 바꾸는 줄이 있습니까?


9

다음과 같은 패턴의 파일이 있습니다.

foo 111
baz
foo 222
baz
foo 333
baz

어느 것으로 바뀔 필요가

foo 111
bar 111
baz
foo 222
bar 222
baz
foo 333
bar 333
baz

따라서로 시작하는 모든 줄을 복제하고 복제본 foo만 변경 foo하지만 나머지 줄 (각각 다른 경우)은 그대로 둡니다. 이것을하는 방법?


정규 표현식에 지옥에 묶이지 않으면 매크로가 정상적으로 작동합니다. 이와 같은 간단한 경우에는별로 중요하지 않지만 조금 더 복잡한 것이 있으면 매우 유효한 대안입니다.
PhilippFrank

답변:


19

여기 있습니다 :

:g/foo/t.|s//bar

분해 :

:g/foo/    " start a global command applied on all lines matching 'foo'
t.         " duplicate the current line (the cursor is now on the new line)
|          " chain a new command
s//bar     " substitute the last searched element with 'bar'

g명령은 검색 패턴을 업데이트하므로 대체 명령에서 패턴을 대체하여 생략 할 수 있습니다. (참조 : :h :g검색 search pattern).


이전 버전 :

:g/foo/norm! yyp:s/foo/bar^M

분해 :

:g            start a global command
/foo/         apply only on lines having 'foo'
norm!         execute a normal command
yyp           duplicate the line
:s//bar       replace foo with bar on the line (the duplicated one)
^M            add enter to execute the substitution

삽입하려면 ^M눌러 Ctrl+venter.

참고 : t명령 에 대해 배우기 전에 원래 "이전"버전을 생각해 냈습니다 . 나는 그것을 떠날 것이지만 그것을 사용하지 않는 것이 좋습니다. 첫 번째는 더 간단합니다.


해결 된 '더 간단한 버전'은 완벽하게 작동했습니다. 그러나 첫 번째 버전은 복제 선이 여전히 foo...으로 시작하는 결과를 가져 왔습니다 .
LB7979

이상하게 ^M설명했듯이 입력 했 습니까?
nobe4

내 나쁜, 잘 읽지 않았다. 첫 번째 해결책도 잘 작동합니다!
LB7979

왜 복잡한 버전을 포함시켜야하는지 모르겠습니다. 더 간단한 버전은 ... 더 간단합니다. ;) (POSIX 호환은 말할 것도 없습니다.) 왜 먼저 넣지 않겠습니까?
와일드 카드

1
처음에 나는 첫 번째 버전을 찾았습니다. 왜냐하면 당시에 알지 못했기 때문에 더 자연 스럽습니다. 그리고 두 번째 버전을 t추가했습니다. 순서를 바꿀 게요 당신 말이 맞아요 POSIX 인 첫 번째는 어떻습니까?
nobe4

1

나는 항상 이와 같은 일을하고 단지 같은 일을합니다 %s/^foo \(.*\)/foo \1\rbar \1/(부분적으로는 복사 기능을 사용하여 영리한 것으로 바꿀 수 없으며 \(.*\)지금까지 근육 기억의 일부인 많은 유사한 작업을 수행하기 때문에 ).

POSIX 호환 (다른 vi 클론에서는 작동하지 않음)이지만 의심되는 대신 ^M( C-VReturn)를 사용 \r하면 대부분의 다른 vi 클론에서는 작동하는 것으로 보입니다.

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