1. 기본적인 편집,명령

vi는 크게 세가지 모드로 나뉘어집니다. 우선 명령모드로 키 입력이 바로 바로 명령이 되는 모드, 다음은 입력모드로 실제 문서를 편집하는 모드, 마지막으로 ex 모 드로 ex명령을 실행시키는 모드입니다. vi를 실행시키면 처음에명령모드 상태에 있게 됩니다. 명령모드에서 : 키를 누르면 ex모드로, a, i 등의 키를 누르면 입력모 드로 전환되어 문서를 편집할 수 있는 상태로 됩니다. 본격적인 내용으로 들어가기 전에 기본적인 편집에 대해서 설명을 하겠습니 다. 특정 파일을 편집하기 위해 열려면 vi [filename]을 shell prompt에서 실행시킵 니다. 이렇게 연 파일을 편집모드로 들어가 편집하려면 i를 입력, 원하는 내용을 입 력한 후 종료하려면 [ESC]ZZ 나 [ESC]:wq를 누르면 저장 후 종료하게 됩니다. 이 정 도는 기본적으로 알아두셔야 지금부터 하는 내용을 따라해 보실 수 있겠죠? 또 기본 적으로 알아두셔야 할 명령이 명령모드에서 u 즉 undo명령입니다. 그래야 잘못 실행 된 명령을 바로 undo할 수 있겠죠...^^
i 현재위치에서 삽입
I 현재줄의 처음 위치에서 삽입
a 현재 위치에서 추가
A 현재줄의 끝 에서 추가
o 새로운 한 줄을 커서 아래줄에 연다.
O 새로운 한 줄을 커서 위줄에 연다.
S 줄을 지우고 삽입모드로
R 현재 위치에서 Relpace 모드로
J 다음줄과 현재줄을 합친다.
~ 대문자<->소문자
. 마지막 명령을 반복한다
u (<-> CTRL-R) 마지막 수정한 것을 취소한다.
U 줄을 처음 상태로 복구한다.

1.1. 편집

1.1.1. 복사, 붙이기, 삭제

텍스트 편집기를 사용하면서 가장 유용한 기능 중에 하나가 반복되는 문자열을 복사해서 다른 곳에 붙이는 기능이라고 생각합니다. vi 역시 이러한 기능을 가지고 있고 vi의 명령어의 특성상 매우 많은 방법으로 이러한 명령을 수행할 수 있습니 다. 명령모드에서 yy라고 입력하면 현재 커서가 위치한 한 줄을 카피(Yanking)하게 됩니다. 또 dd는 현재 행을 삭제하게 되는데 이 역시 삭제가 이루어지면서 버퍼에 복 사가 되어있습니다. yy나 dd로 버퍼에 들어간 내용을 붙이려면 붙이고자 하는 곳 한 줄 위에서 p를 입력하면 됩니다. 짐작하시듯이 y키가 복사를 하는데 사용되는 키이고 d가 삭제에, p가 붙이기에 사용되는 키입니다. 명령모드에서 사용되는 명령들은 명령 앞에 숫자를 입력한 후 명령을 내리면 그 횟수만큼 명령을 반복하게 됩니다. 쉽게 2yy 라고 입력하면 2줄을 복사하리라는 것을 생각할 수 있습니다. 뒤에서 나오게 되는 이동에 관련된 명령과 조합하면 복사나 삭제를 원하는 영역에서 해 낼 수 있습니다. 우선 여기서는 복사에 사용되는 키가 y키, 삭제에 사용되는 키가 d, 붙이기에 사 용되는 키가 p키라는 것만 숙지하고 넘어갑시다. 참 한가지 빠뜨리고 넘어갈 뻔했군요. X 나 x키가 명령모드에서 삭제에 사용됩니다. 문자 위에서 x를 누르면 위치한 문 자가 삭제되고 X를 누르면 [bs]키처럼 동작을 합니다.
-copy-
cw 한 단어
2cw or c2w 두 단어
cc 한 행
c$ or C 커서 위치에서 행의 끝까지
cO 커서 위치에서 행의 처음까지
r 한 문자 변경
-delete-
dw 한 단어
2dw or d2w 두 단어
dd 한 행
d$ or D 커서 위치에서 행의 끝까지
dO 커서 위치에서 행의 처음까지
x or X 한 문자 변경
-yanking-
yw 한 단어 
2yw or y2w 두 단어
yy 한 행
y$ or Y 커서 위치에서 행의 끝까지
yO 커서 위치에서 행의 처음까지
y1 or yh 한 문자 변경

1.1.2. Named 버퍼 사용

보통의 에디터의 경우에는 어떤 특정 문자열을 새로 복사하면 이전에 복사했 던 문자열이 지워지게 됩니다. vi는 a-z까지의 이름을 갖는 버퍼에 각각을 유지하여 복사 해 둘 수 있는 매우 편리한 기능을 제공합니다. 이러한 기능을 named buffer라 하고 사용방법은 모든 명령모드에서의 명령 앞에 a~z까지의 버퍼명 a ~ z을 붙여주 는 것입니다. 위에서 복사를 했던 것을 다시 해보면 ayy를 누르면 현재 줄이 a 버 퍼에 복사가 됩니다. 이것을 다시 붙이기를 하려면 ap를 입력하면 되겠지요. 이미 있는 버퍼에 내용을 추가하거나 처음부터 버퍼에 써 넣는 방법을 설명 하겠습니다. 이미 어떤 버퍼에 내용이 들어가 있고 그 뒤에 내용을 추가하고 싶은 경 우가 생기죠. 이런 경우 추가는 버퍼 이름의 대문자를 사용합니다. Ayy와 같이 현재 줄을 버퍼에 추가하거나, ex모드에서 특정 문자열이 있는 줄을 모두 복사해두고 싶은 경우 :g/string/y A 이런 식으로 사용하는 것이죠. 복사등을 하지 않고 버퍼에 직접 써넣으려면 q명령을 사용합니다. q 다음에 버퍼명을 누르면 화면하단에 recording이라는 표시가 나오고 지금부터 하는 키 입력 은 선택한 버퍼명에 들어가게 됩니다. 키입력이 끝나면 다시 q를 누르면 됩니다. 뒤에서 ex모드에서 사용하는 방법이나 @-function에 사용할 수 있는 방법을 설명하겠습니다. 여기서는 이 정도만 알고 넘어가도록 하죠. (주: vim에서는 register라고 하는군요.

1.1.3. 여러 문서의 편집

vi에서 여러 문서를 동시에 열기 위해서는 vi [filename1] [filename2]...의 형태로 열고자 하는 파일을 뒤에 이어서 써 줍니다. 그럼 동시에 여러 문서를 편집하 게 되죠. 그리고 각 문서 사이의 전환은 :n키와 :N을 이용해서 합니다. 즉 vi test1 test2로 두 파일을 열어서 작업을 하고 있다면 :n을 입력하면 test2로 편집이 넘어가 게 됩니다. 다시 :N 또는 :prev을 입력하면 test1을 편집할 수 있습니다. 또 현재 어 떤 파일을 편집중인지 확인하려면 :args를 입력하면 현재 열린 모든 파일 중에 현재 편집중인 파일이 대괄호로 둘러싸여 표시됩니다. 열린 파일이 많아서 여러 문서를 건 너뛰어 편집해야 하는 경우에는 n이나 N앞에 skip할 파일 개수를 써주면 됩니다. :4n 이런 식이 되겠죠.

1.2. 이동

문서내용을 수정하려면 편집하고자 하는 위치로 먼저 이동하여야 편집이가 능하겠지요. vi는 다른 편집기와는 비교도 되지 않을 만큼 많은 이동 방법을 제공합 니다. 이동명령은 다른 명령(복사, 삭제, 붙이기)등과 조합해서 사용하기 때문에 확 실히 알아두시는 것이 좋습니다. 제 나름대로 분류를 가까운 거리의 이동에서 원거리 이동까지 분류를 해 보았습니다.

1.2.1. 짧은 이동

가장 기본적인 이동이 명령모드 상에서 h, j, k, l키를 이용한 이동입니다. 차례로 좌, 하, 상, 우로의 이동을 나타냅니다. 역시 다른 명령모드 명령과 마찬가지 로 회수를 명령 앞에 넣어서 반복할 수 있습니다. 요즘은 대부분 커서 키를 지원하고 있지만 손가락이 오가는 거리 상 사용하지 않으시는 것이 좋습니다. 단어간의 이동은 w, b, e, E키로 합니다. w키는 다음 단어의 첫 번째 문자로 이동을 합니다. b는 반대로 앞 단어의 첫 번째 문자로의 이동을 나타냅니다. e, E는 첫 번째 문자로의 이동이 아닌 단어의 마지막 문자로의 이동입니다. 역시 회수를 앞 에 넣어서 몇 단어를 한 번이 이동할 수 있습니다. 이 밖에도 현재행 상에서 이동을 하는 명령들이 많이 있습니다. 0키를 누르 면 현재 행의 맨 앞으로 이동합니다. ^ 이나 | 역시 행의 맨 처음으로 이동합니다. 0 키는 행의 처음에 공백이 나오다 문자열이 나오는 경우에는 공백을 무시하고 맨 처음 나타나는 문자로 이동합니다. 하지만 ^ 이나 |는 0번째 열로 이동하게 됩니다. 특정 열로 이동하려면 [숫자]| 즉 10번째 열로 이동하려면 10|을 입력하면 10번째 열로 이 동을 하게 됩니다. 현재 행의 끝으로 이동하려면 $기호를 사용합니다. 이제 행간의 이동입니다. 한 행 밑으로 이동은 + 또는 [enter], 위로의 이동 은 - 키를 사용합니다. 10[enter]라고 입력해 보십시오. 엔터를 한 번입력하면 한 행밑으로 이동하지만 한 번에 10 행씩 팍팍 떨어지지 않습니까? 10+도 같은 결과를 보여줍니다.
h, j, k, l 좌, 하, 상, 우
+ or [enter] 다음줄의 첫번째 문자로
- 이전줄의 첫번째 문자로
e, E 단어의 끝으로
w, W 다음 단어로
b, B 이전 단어로
$ 행의 끝으로
0 행의 처음으로 ( 'A' 인 경우 A앞으로 커서이동)
^ 행의 처음으로 ( 'A' 인 경우에도 맨앞으로 커서이동)
), ( 다음, 이전 문장의 처음으로
}, { 다음, 이전문단의 처음으로
]], [[ 다음, 이전 구절의 처음으로

1.2.2. 원거리 이동

이제 조금 원거리 이동으로 넘어갑니다. 문서가 20000행 정도 된다고 합시 다. 처음에 문서를 열게 되면 커서는 1행에 위치합니다. 에러가 10000행 정도에 발생 한 소스코드를 수정한다고 치면, 어떻게 이동하면 좋을까요? 물론 뒤에서 파일 열기 에서 배우겠지만 현재까지 저희가 언급한 바로는 10000+를 하든지 해야겠지요. 물론 이렇게 해도 되겠지만 특정 행으로 직접 이동하는 명령이 있습니다. 바로 G명령입니 다. 10G라고 입력하면 10번째 행으로 이동하게 되는 것이죠. 다른 방법으로는 ex명령 에서 :10라고 입력하고 엔터를 입력하면 그 행으로 이동하게 됩니다. 맨 처음 줄로의 이동은 gg 나 1G 나 :1 등을 사용하고 마지막 줄로의 이동은 G 나 :$ 등이 가능합니 다. 여기서 $는 뒤에서 언급을 하겠지만 ex모드에서는 마지막 줄을 나타냅니다. 명령 모드에서는 행의 끝으로 이동에 사용되었죠.
^F 한 화면 앞으로 스크롤 (means CTRL-F)
^B 한 화면 뒤로 스크롤
^D 반 화면 앞으로 스크롤
^U 반 화면 뒤로 스크롤
^E 한 줄 앞으로 스크롤
^Y 한 줄 뒤로 스크롤
H 화면의 맨 위줄로 ( nH인 경우 맨 위에서 n행 밑으로 )
M 화면의 중간 줄로
L 화면의 맨 아래줄로 ( nL인 경우 맨 밑에서 n행 위로 )

1.2.3. 찾기로 이동

자세한 내용의 찾기는 3장에서 다를 것이고 여기서는 이동에 사용되는 찾기 명령에 대해서 설명하도록 하겠습니다. 현재 행에서 순방향으로의 특정 문자를 찾을 때는 f 키를 사용합니다. 현재 행에서 커서위치에서 첫 번째 나타나는 o 문자까지 이 동하고 싶다면 fo를 입력하면 됩니다. 반대 방향이라면 Fo를 입력하면 되겠죠. 이 명 령의 반복은 어떻게 할까요? 다른 명령처럼 앞에 반복회수를 명시해도 되지만 찾은 후에 다시 찾기를 같은 방향으로 하려면 키를 반대방향으로 하려면 , 키를 사용해 서 명령을 반복합니다. 한 행을 떠나서 순방향으로 어떤 패턴이 나타나는 곳으로 이동하려면 /pattern을 역시 반대 방향이라면 ?pattern을 입력하면 됩니다. 이 역시 같은 방향으 로 반복을 하려면 n, 반대 방향은 N키를 사용합니다.
/pattern 문자열의 처음에서 앞으로 검색
?pattern 문자열의 처음에서 뒤로 검색
n 검색을 다시 반복 (같은 방향)
N 검색을 다시 반복 (반대 방향)
fx 현재 줄에서 x가 있는 곳으로 이동 (앞으로)
Fx 현재 줄에서 x가 있는 곳으로 이동 (역방향)
tx n행 밑에서 x가 있는 곳으로 이동
Tx n행 위에서 x가 있는 곳으로 이동
; 줄에서 찾기를 같은 방향으로 반복
, 줄에서 찾기를 반대 방향으로 반복
nG, :n 행 이동 n번째 줄로 이동 (n이 생략되면 마지막줄로) --변환자 주: 이
기능은 :n 으로 하는것이 편합니다 :)
nl 열 이동 (n이 생략되면 처음 열로)
*  현재 커서가 위치한 단어 찾기 (앞방향)
# 현재 커서가 위치한 단어 찾기 (역방향)

1.2.4. 마크를 이용한 이동

책을 읽다 북마크를 하는것처럼 문서를 편집하다가 특정 부분을 마크할수 수 있으면 편리하겠지요. vi에서는 역시 알파벳 개수만큼의 마크를 하고 마크한 곳이나 그 줄로 바로 이동할 수 있습니다. 우선 마크를 하려면 ma ~ mz를 마크 할 곳에서 입 력합니다. 마크한 곳으로 이동은 두 가지가 가능합니다. 즉 마크한 줄과 열이 일치하 는 이동은 `a ~ `z 으로 마크한 줄의 처음으로 이동은 'a ~ 'z를 이용합니다.
mx 현재 위치를 x 이름의 마크로 저장	
`x 마크한 위치(행, 열)로 이동		
'x 마크한 줄로 이동			
`` 이전에 마크한 위치로 이동
'' 이전에 마크한 줄로 이동	

1.3. 파일 저장, 열기, 종료

파일을 열 때 여러 가지 옵션을 주어서 열 수 있습니다. 즉 특정 행에 커서 가 위치하도록 열 수 있는데, 마지막 줄에 위치하려면 vi + [filename] 과 같이 열 고, n번째 행에 위치시키려면 vi +n [filename] 과 같은 방식으로 열면 됩니다. 특정 문자열이 있는 줄에 커서를 위치시키려면 vi +/pattern [filename]로 엽니다. vi +R [filename] 은 파일을 읽기 전용으로 엽니다. 파일의 저장을 살펴볼까요. 파일을 저장하면서 종료하는 방법은 맨 처음에 두 가지를 설명했었습니다. :wq 와 ZZ입니다. 다른 저장방법이라면 :x 이 명령은 파 일이 변경되었을 때에는 저장하고 종료를 하지만 아니면 그냥 종료를 합니다. ZZ와 같은 기능이 같죠. 저장과 열 때 ex모드에서 사용하는 몇 가지 기호를 알아두시면 편 리합니다. 즉 %는 작성중인 파일명을 나타냅니다. 따라서 현재 파일을 편집 중에 백 업파일을 저장하고 싶다면 :w %.bak 이런 식으로 하시면 쉽게 백업을 만들 수 있습니 다. 그리고 #는 alternative 파일을 나타낸다고 하는데 이전에 열어서 작성한 파일을 나타냅니다. vi file1 으로 편집을 하다가 :e file2로 편집 파일을 새로 연 경우 다 시 먼저의 file1을 열려면 :e # 라고 하시면 됩니다.
vi [filename] file 열기					
vi [filename1] [filename2 여러 파일 열기			
view [filename] 또는 vi -R [filename]읽기 전용으로 열기
vi + [filename] 열고 마지막 행에 위치		
vi +n [filename] 파일을 열고 n 번째 행에 위치	
vi +/pattern [filename] 패턴이 나타나는 곳에 행 위치	
ZZ 또는 :x 변경된 파일이면 저장하고 종료
:wq 저장하고 종료				
w 파일의 저장							
:<범위>w [filename] 특정 범위만 저장		
:<범위>w >> [filename] 특정 범위를 다른파일에 덧붙임	

1.4. 정리 및 연습문제

명령 중에서 대부분이 case가 다르면 방향만 반대로 작용하는 경우가 많습니 다. Ff, Oo, Pp, Tt, Nn, Xx등은 case에 따라서 방향이 반대인 경우입니다. 다른 문 자들도 case에 따라서 약간씩 의미가 달라졌음을 볼 수 있습니다. 이점에 유의해서 명령을 기억하면 쉽게 기억할 수 있습니다. 자 위에서 배운 내용들을 조합해서 키 입력을 만들어 봅시다. 예문을 가지고 설명을 하도록 하겠습니다. 아래와 같은 문서를 편집하고 있고 현재 커서가 4번째 줄 의 sutff의 s에 위치해 있다고 합시다. 천천히 따라오세요. stuff 단어 하나만 지우 려면 dw를 입력하면 됩니다. 다음 단어인 goes까지 같이 지우려면 dw를 두 번 반복하 면 되겠지요? 2dw, 혹은 d2w를 입력해도 됩니다. 현재 커서 위치에서 2w 즉 두 단어 이동한 곳까지 지우는 것이죠. d다음이 이동명령이 오면 이동한 곳까지 지우는군 요... 그럼 우리가 배운 이동명령을 총 동원해 보도록 하죠. d$ 이면 $가 행의 끝까 지이니까 stuff부터 행 끝까지 지워지겠군요. 이 명령은 D를 입력해도 같은 결과를 나타냅니다. 이번엔 찾기로 이동과 조합해 봅시다. dfl을 입력하면 첫 번째 l이 나타나는 곳까지 커서가 이동하니까 l까지 지워지겠죠? d/bash를 입력해 봅시다. 6행에 bash앞 까지 삭제가 되었나요? 자 이번엔 mark로도 이동이 가능하다고 했으니 mark를 이용해서 지워봅시다. 7행의 some의 s위에서 ma라고 합시다. 다시 stuff의 s로 돌아가서 d`a라고 입력해 보 세요. 생각했던 것처럼 나왔다면 다른 조합들을 생각해 보시길 바랍니다. 복사는 d대 신 y를 넣어주면 됩니다. 그럼 연습문제를 풀어보세요.
# /etc/bashrc
# System wide functions and aliases
# Environment stuff goes in /etc/profile

# For some unknown reason bash refuses to inherit
# PS1 in some circumstances that I can't figure out.
# Putting PS1 here ensures that it gets loaded every time.		
PS1=[\u@\h \W]\\$ 
alias which=type -path
   연습문제 2
문제 1) 현재 커서 위치가 unknown의 u에 있다고 하자. 단 각각 문제에 결과는 
다음 문제에 영향을 미치지 않는다고 가정... 

현재위치에서 그줄 끝까지 삭제, 복사 
4줄 복사 후 마지막 줄 아래에서 삽입, 복사 
현재 위치에서 figure out의 out앞 까지 삭제, 복사 
현재 줄에서 마지막 줄까지 삭제, 복사 
현재 위치에서 줄의 처음까지 삭제, 복사 
현재 위치에서 25열까지만 삭제, 복사 

문제 2)
1.위에서 3번째 행과 4번째 행을 합쳐라. 

삭제 : d$, D  복사 : y$ 
4yyGp 
삭제 : d/out 복사 : y/out 
삭제 : dG, 6dd 복사 : yG, 6yy 
삭제 : d0, d|, d1|, 3db, d3b, d?#, dF# 복사 : y0, y|, y1|, 3yb, y3b, 
y?#, dF# 
삭제 : d25| 복사 : y25| 

2. 두 줄을 합치는 명령을 표에서 찾아서 해보도록.