*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)는 얼마인지 알 수 있습니다. 파일 중 일부분만 단어 수를 세고 싶다고 합시다. 세고 싶은 부분의 처음으로 가서 "gCTRL-G
"를 누르고, 끝으로 가서 "gCTRL-G
"를 누른 후, 보고 있는 단어의 위치를 암산으로 빼면 단어 수를 계산할 수 있습니다. 하지만 더 쉬운 방법도 있습니다. 시각 모드에서 세고 싶은 부분을 선택한 후, gCTRL-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