USR_12

*usr_12.txt*	Vim version 7.4 대상.  새로 고침: 2007년 5월 11일

		      VIM 사용설명서 - Bram Moolenaar 저
				       정지용 역

				 멋진 기술들


Vim에서는 몇 가지 명령을 조합하는 것만으로 수많은 일들을 할 수 있습니다.  이번
장에서는 그 중 몇 가지 유용한 조합들을 살펴보겠습니다.  새로운 명령도
등장합니다만, 대부분은 앞의 장들에서 살펴본 명령을 사용할 것입니다.

|12.1|	단어 바꾸기
|12.2|	"성, 이름"을 "이름 성"으로 바꾸기
|12.3|	목록 정렬하기
|12.4|	줄의 순서 바꾸기
|12.5|	단어 수 세기
|12.6|	매뉴얼 페이지 찾기
|12.7|	빈칸 없애기
|12.8|	단어가 어디서 쓰였는지 찾기

다음 장: |usr_20|  명령줄 명령 빨리 치기
이전 장: |usr_11|  작업 복구하기
   차례: |usr_toc|


*12.1*	단어 바꾸기

substitute 명령은 한 단어를 모두 다른 단어로 바꿔줍니다:

	:%s/four/4/g

범위를 나타내는 "%"는 파일의 모든 줄에서 바꾸기를 하라는 의미입니다.  마지막
"g"는 한 줄에 있는 모든 단어를 바꾸도록 지시합니다.
   하지만 위와 같이 하는 경우 만약 파일에 "thirtyfour"같은 부분이 있다면,
"thirty4"로 의도치 않게 바뀌어버립니다.  이렇게 잘못 바뀌는 것을 막기 위해서는
단어의 앞에 "\<"를 써주면 됩니다:

	:%s/\<four/4/g

하지만 아직도 "fourteen"이란 내용이 있는 경우에는 잘못 바뀔 수 있습니다.
따라서 단어의 마지막을 나타내기 위해 "\>"를 써주어야 합니다:

	:%s/\<four\>/4/g

프로그래밍을 중에, 주석 안에 있는 "four"는 바꾸면서 코드 내용에 들어있는
"four"는 바꾸지 않고 싶다고 가정해봅시다.  이런 조건을 지정하기는 어렵기
때문에, "c" 를 마지막에 추가하여 바꿀 때마다 사용자에게 물어보도록 하면
됩니다:

	:%s/\<four\>/4/gc


여러 파일에서 바꾸기
--------------------

여러 파일에서 단어 하나를 바꾸고 싶다고 합시다.  각 파일을 일일이 열어서 직접
바꿔줘도 되겠지만, 명령어 기록과 재생을 이용하면 훨씬 빠르게 할 수 있습니다.
   ".cpp"로 끝나는 C++ 파일들이 있는 디렉터리가 있다고 합시다.  "GetResp"라는
함수를 "GetAnswer"로 바꾸고 싶다면 다음과 같이 하면 됩니다.

	vim *.cpp		모든 C++ 파일을 인자로 하여 Vim을
				실행시킵니다.  일단 첫 번째 파일이 열릴
				것입니다.
	qq			q 레지스터에 기록을 시작합니다.
	:%s/\<GetResp\>/GetAnswer/g
				첫 번째 파일에서 바꾸기를 합니다.
	:wnext			저장하고 다음 파일로 넘어갑니다.
	q			기록을 끝냅니다.
	@q			q 레지스터에 기록된 명령을 수행합니다.
				바꾸기와 ":wnext"가 수행될 것입니다.  에러가
				발생하지 않았는지 확인해보십시오.
	999@q			나머지 파일에 대해서도 q 레지스터에 기록된
				명령을 수행합니다.

마지막 파일에서는 ":wnext"로 다음 파일로 이동할 수 없기 때문에 에러가 발생할
것입니다.  그러면 명령 수행이 끝납니다.  여러 파일에 들어있는 모든 내용이
바뀌었을 것입니다.

	Note:
	기록한 명령어가 수행될 때, 에러가 발생하면 수행이 멈추게 됩니다.
	따라서 명령어를 기록할 때는 에러가 발생하지 않도록 주의해야 합니다.

한 가지 빠뜨린 것이 있습니다.  만약 .cpp 파일 중에 "GetResp"가 한 번도 나오지
않는 파일이 있다면, 바꾸기 수행 중에 에러가 발생하면서 기록된 명령의 재생이
멈추게 됩니다.  이를 막기 위해서는 substitute 명령의 마지막에 "e"를 붙여 주면
됩니다:

	:%s/\<GetResp\>/GetAnswer/ge

"e"는 ":substitute" 명령어가 일치하는 문자열을 찾지 못하더라도 에러를
발생시키지 않도록 지시합니다.


*12.2*	"성, 이름"을 "이름 성"으로 바꾸기

다음과 같은 영어 이름 목록이 있다고 합시다:

	Doe, John 
	Smith, Peter 

이를 다음과 같이 바꾸고 싶다면:

	John Doe 
	Peter Smith 

다음 명령으로 한 번에 바꿀 수 있습니다:

	:%s/\([^,]*\), \(.*\)/\2 \1/

차근차근 살펴봅시다.  물론 바꾸기(":substitute") 명령이 사용되었습니다.  "%"는
바꾸기 적용 범위를 나타내는데, 파일 전체를 의미합니다.  따라서 이 바꾸기는
파일의 모든 줄에 적용 됩니다.
   바꾸기 명령에 사용되는 인자는 "/예전/새로운/" 형태입니다.  "예전" 패턴과
"새로운" 문자열은 '/'(슬래시)로 구분됩니다.  "예전" 패턴의 내용을 살펴봅시다:
							\([^,]*\), \(.*\) 

	첫 번째 \( \) 안의 내용은 '성' 부분에 대응됨	\(     \)
	    콤마가 아닌 모든 것에 대응됨		  [^,]
	    몇 개든 상관없음				      *
	", "라는 문자열 자체에 대응됨				 ,
	두 번째 \( \) 안의 내용은 '이름' 부분에 대응됨		   \(  \)
	    모든 문자에 대응됨					     .
	    몇 개든 상관없음					      *

"새로운" 문자열 부분에는 "\2", "\1"이 있습니다.  이런 것을
후방참조(backreference)라고 합니다.  후방참조는 패턴의 "\( \)"부분에
대응된 것을 가리킵니다.  "\2"는 두 번째 "\( \)"에 대응된 문자열을 가리키는데,
위 예에서는 '이름' 부분입니다.  "\1"은 첫 번째 "\( \)"부분, 즉 '성'부분을
나타냅니다.
   "새로운" 문자열 부분에는 후방참조가 9개까지 사용될 수 있습니다.  "\0"은
특별히 패턴 전체에 대응된 내용을 가리킵니다.  바꾸기 명령에는 몇 가지 특수
기능이 더 있습니다.  |sub-replace-special| 에서 살펴보시기 바랍니다.


*12.3*	목록 정렬하기

Makefile에는 다음과 같은 파일 목록이 자주 쓰입니다:

	OBJS = \ 
		version.o \ 
		pch.o \ 
		getopt.o \ 
		util.o \ 
		getopt1.o \ 
		inp.o \ 
		patch.o \ 
		backup.o 

이 목록을 정렬하려면 외부 명령어인 "sort"를 사용하면 됩니다:

	/^OBJS
	j
	:.,/^$/-1!sort

"OBJS"로 시작하는 줄인 맨 첫 줄로 이동합니다.  그리고 한 줄 내려와서 빈 줄이
나타날 때까지의 내용을 처리하게 됩니다.  시각 모드에서 정렬할 범위를 선택한 후
"!sort" 명령을 입력해도 됩니다.  시각 모드에서 선택하는 편이 보통은 더 쉽지만,
정렬할 내용이 많을 땐 그렇지 않을 수도 있습니다.
   결과는 다음과 같습니다:

	OBJS = \ 
		backup.o 
		getopt.o \ 
		getopt1.o \ 
		inp.o \ 
		patch.o \ 
		pch.o \ 
		util.o \ 
		version.o \ 


Makefile에서 각 줄의 맨 마지막에 있는 백슬래시는 다음 줄로 계속된다는
의미입니다.  그런데, 정렬을 했더니 엉켜버리고 말았습니다.  "backup.o"가 있는
줄이 백슬래시로 끝나지 않으므로, 이 줄에도 백슬래시를 추가해야 합니다.
   가장 간단한 방법은 "A \<Esc>"로 백슬래시를 추가해주는 것입니다.  맨 마지막
줄에 있는 백슬래시는 그 다음에 빈 줄이 있기만 하면 되므로 그냥 놔두면 됩니다.
나중에 새로운 내용이 추가되거나 또 순서를 바꾸더라도 문제가 없도록 말입니다.


*12.4*	줄의 순서 바꾸기

|:global| 명령어와 |:move| 명령을 섞어서 모든 줄을 차례대로 맨 첫 줄로
옮기도록 해봅시다.  결과적으로 맨 첫 줄이 마지막으로 가고 맨 마지막 줄이 맨
처음으로 가서 역순이 됩니다.  명령어는:

	:global/^/m 0

줄여서:

	:g/^/m 0

입니다.  "^" 정규표현식은 줄의 시작에 대응됩니다 (줄이 빈 줄이더라도).
|:move| 명령어는 대응된 줄을 실제로는 존재하지 않는 0번째 줄의 다음으로
옮기고, 결과적으로 현재 대응된 줄이 파일의 첫 번째 줄이 됩니다.  |:global|
명령은 줄이 바뀌기 전의 순서대로 처리를 합니다. 따라서 |:global|은 차례대로
다음 줄을 처리하고, 계속해서 대응되는 줄을 파일의 맨 첫 줄로 옮기게 됩니다.

이 명령을 특정 범위에 대해서만 쓸 수도 있습니다.  먼저 범위의 첫 번째 줄 위로
커서를 옮기고 "mt"로 마크를 만듭니다.  커서를 범위의 마지막 줄로 옮긴 후, 다음
명령어를 입력합니다:

	:'t+1,.g/^/m 't


*12.5*	단어 수 세기

가끔 몇 단어(한국어의 경우, 어절) 이하로 글을 써야할 때가 있습니다.  이때
Vim으로 단어의 수를 셀 수 있습니다.
   파일 전체의 단어를 세고 싶다면, 다음 명령어를 쓰면 됩니다:

	g CTRL-G

g를 입력한 후, 스페이스바를 누르지 마십시오.  공백은 읽기 쉬우라고 넣은
것입니다.
   다음과 같이 결과가 표시됩니다:

	Col 1 of 0; 라인 141 of 157; 단어 748 of 774; 바이트 4489 of 4976 

몇 번째 단어(748)를 보고 있는지, 총 단어 수(774)는 얼마인지 알 수 있습니다.

파일 중 일부분만 단어 수를 세고 싶다고 합시다.  세고 싶은 부분의 처음으로
가서 "g CTRL-G"를 누르고, 끝으로 가서 "g CTRL-G"를 누른 후, 보고 있는 단어의
위치를 암산으로 빼면 단어 수를 계산할 수 있습니다.  하지만 더 쉬운 방법도
있습니다.  시각 모드에서 세고 싶은 부분을 선택한 후, g CTRL-G를 누르면 다음과
같이 결과가 표시됩니다:

	Selected 5 of 293 라인; 70 of 1884 단어; 359 of 10928 바이트 

이 밖의 단어나 줄 등을 세는 방법들은 |count-items|를 참고하십시오.


*12.6*	매뉴얼 페이지 찾기

셸 스크립트나 C 프로그램을 작성하다보면, 명령어나 함수의 매뉴얼 페이지를 찾고
싶을 때가 있습니다(유닉스 환경에만 해당됩니다).  간단한 방법은 다음과
같습니다: 커서를 도움말을 찾고 싶은 단어 위로 옮긴 후, 다음 버튼을 누릅니다

	K

Vim은 외부 명령어 "man"을 그 단어에 대해 실행할 것입니다.  만약 매뉴얼
페이지가 있다면 화면에 표시됩니다.  일반적인 페이저(pager, 결과를 화면에 한
페이지씩 보여주는 프로그램으로 "more"같은 프로그램이 해당됩니다)가 사용되며,
끝까지 본 뒤 <Enter>를 누르면 Vim으로 다시 돌아올 것입니다.

하지만 이렇게 되면 매뉴얼 페이지와 작업 중인 파일을 동시에 볼 수 없습니다.
Vim 창에서 매뉴얼 페이지를 함께 볼 수 있는 방법이 있습니다.  먼저 매뉴얼
페이지의 파일 형식 플러그인을 불러옵니다:

	:runtime! ftplugin/man.vim

매뉴얼 페이지를 자주 본다면 이 명령을 vimrc파일에 넣어두어도 됩니다.  이제
":Man" 명령으로 매뉴얼 페이지를 Vim의 창을 열어 볼 수 있습니다:

	:Man csh

매뉴얼 페이지는 강조가 되어있으며, 이리저리 스크롤도 가능합니다.  이로써
도움말을 볼 수 있고, CTRL-W w를 눌러서 작업 중이던 창으로 전환할 수도
있습니다.
   특정한 섹션에서 매뉴얼 페이지를 찾고 싶다면, 섹션 번호를 먼저 넣으면
됩니다.  예를 들어 섹션 3에서 "echo"의 매뉴얼 페이지를 찾고 싶다면:

	:Man 3 echo

"단어(1)"형식으로 표시되는 다른 매뉴얼 페이지를 보고 싶다면, 해당 단어로
이동해서 CTRL-]를 누르면 됩니다.  ":Man" 명령어를 또 사용해도 새로운 창을
만들지 않고 이미 만들어진 창에 매뉴얼 페이지를 보여줄 것입니다.

현재 커서가 있는 단어의 매뉴얼 페이지를 보고 싶다면 다음 명령을 사용하면
됩니다:

	\K

(<Leader>를 재정의하여, 백슬래시 대신 다른 키를 사용할 수 있습니다).

만약 아래와 같은 내용을 편집하다가 "strstr()"의 반환 값을 알고 싶어졌다고
합시다:

	if ( strstr (input, "aap") == ) 

커서를 "strstr"위로 옮긴 후, "\K"를 입력하면, 창이 열리면서 strstr()의 매뉴얼
페이지가 표시될 것입니다.


*12.7*	빈칸 없애기

줄 끝에 있는 빈칸이나 탭 등은 종종 쓸모없고 지저분하게 보입니다.  모든 줄에서
맨 끝의 공백을 지우기 위해서는 다음 명령을 사용하면 됩니다:

	:%s/\s\+$//

"%" 범위가 사용되었으므로, 파일 전체에 적용됩니다.  ":s"(바꾸기) 명령이
사용하는 패턴은 "\s\+$"입니다.  이 패턴은 공백(\s)이 줄의 맨 끝에($) 하나
이상(\+) 있는 경우에 대응됩니다.  패턴을 쓰는 방법은 나중에 |usr_27|에서
보실 수 있습니다.
   바꾸기 명령의 "새로운" 문자열 부분은 다음과 같이 비어있습니다: "//".
따라서 아무 것도 새로 삽입되지 않고, 공백을 지우는 효과만 나게 됩니다.

공백이 아무 의미 없이 사용되는 또 다른 예는 탭 문자 앞에 공백이 있는
경우입니다.  이러한 공백을 지우더라도 실질적인 공백은 바뀌지 않습니다만, 꼭
항상 그런 것은 아닙니다.  따라서 손으로 확인해가며 지우는 것이 좋습니다.  다음
찾기 명령을 사용합시다:

	/

보이지는 않습니다만, 위 명령에는 공백과 탭이 있습니다.  즉,
"/<Space><Tab>"입니다.  화면의 내용이 바뀌는지 확인하며 "x"를 사용하여 공백을
지웁시다.  만약 화면에 보이는 공백의 크기가 바뀌었다면 탭을 추가하여
복구하도록 합시다.  "n" 키를 눌러 다음 불필요한 공백을 찾고, 더 이상 일치하는
곳이 없을 때까지 반복하면 됩니다.


*12.8*	단어가 어디서 쓰였는지 찾기

만약 유닉스 사용자라면, Vim과 "grep"을 조합하여 어떤 단어가 여러 파일들의
어디에서 쓰였는지 찾을 수 있습니다.  예를 들어 프로그램을 짜는 중에 어떤
변수가 사용된 모든 곳을 찾아 고치고 싶을 때 매우 유용한 기능입니다.
   "frame_counter"라는 단어가 사용된 모든 C 프로그램 파일을 고치고 싶다고
합시다.  다음 명령을 사용하면 됩니다:

	vim `grep -l frame_counter *.c`

명령을 자세히 살펴보도록 하겠습니다.  "grep" 명령어는 여러 파일들에서 단어를
찾습니다.  -l 인자가 주어졌으므로 단어가 포함된 파일들의 이름만 보여주고,
포함된 부분의 내용은 보여주지 않을 것입니다.  찾는 단어는 "frame_counter"지만,
여기에 정규표현식을 넣을 수도 있습니다.  (Note: "grep"에서 사용하는
정규표현식이 Vim에서 사용하는 정규표현식과 완전히 같지는 않습니다.)
   전체 명령이 백틱(`)으로 싸여있는데, 이는 유닉스 셸이 이 명령어를 수행한 후,
그 결과가 명령줄에 입력된 것처럼 동작하라는 의미입니다.  여기서는 "grep"
명령이 수행되어 파일들의 목록이 만들어진 후, 이 목록이 Vim의 명령어 인자로
전달 됩니다.  그 결과 Vim은 "grep"의 결과인 파일들을 열게 됩니다.  ":first"나
":next"같은 명령으로 파일들을 바꾸어가며 편집할 수 있습니다.


줄 단위로 찾기
--------------

위 명령은 단어가 어느 파일에 포함되어있는지 만을 찾아서 알려줍니다.  따라서
파일이 열린 후 파일 안에서 그 단어가 어디에 있는지 또 찾아야 합니다.
   Vim은 여러 파일에서 문자열을 찾기 위한 명령을 내장하고 있습니다.  예를 들어
C 프로그램 파일들에서 "error_string"을 모두 찾고 싶다면, 다음 명령어를
사용하면 됩니다:

	:grep error_string *.c

위 명령은 Vim이 지정된 파일들(*.c)에서 "error_string"을 찾도록 지시합니다.
Vim은 첫 번째 찾은 파일을 열고 첫 번째 찾은 줄에 커서를 위치시킵니다.
다음으로 찾은 줄(다른 파일이더라도 상관없습니다)로 이동하기 위해서는 ":cnext"
명령을 사용하면 됩니다.  이전에 찾았던 위치로 가려면 ":cprev" 명령을 사용하면
됩니다.  ":clist" 명령은 전체 찾은 결과와 함께, 현재 어디를 편집하고 있는지
보여줍니다.
   ":grep" 명령은 유닉스에서는 외부 명령 "grep"을 사용하고, 윈도에서는
"findstr"을 사용합니다.  이 명령은 'grepprg' 옵션으로 바꿀 수 있습니다.


다음 장: |usr_20|  명령줄 명령 빨리 치기

저작권: |manual-copyright| 참고  vim:tw=78:ts=8:ft=help:norl:

Generated by vim2html on 2013. 12. 14. (토) 20:47:01 KST