vi가 두려운 분들께

    저 자 : 이승현

     

 

    유닉스를 처음 접하는 사람에게 있어서 vi는 아주 골치 아픈 존재입니다. 특히 이미 DOS 등과 같은 다른 운영 체제에서 문서 편집기를 써 본 경험이 있는 사람들에게 vi 의 괴상스럽기까지 한 사용법 때문에 당황하기 마련이지요. 그렇지만 피해갈 생각은 하지 마시기 바랍니다. 물론, 유닉스 환경에서 vi 보다 우수한(또한 편리한) 문서 편집기가 있을 수는 있지만, vi를 대신할 수는 없으니까요.

    어떤 유닉스 환경에서도 제공되는 기본적인 문서 편집기 중의 하나이거든요. 아무리 좋아도 쓰려고 하는 시스템에 설치되어 있지 않으면 무슨 소용이 있겠습니까? 더구나 vi 는 적어도 그와 같은 기본적인 편집기 중 가장 쓰기에 편리하고 강력한 기능을 가진 문서 편집기입니다. vi 보다 더 쓰기 불편한 문서 편집기가 있다는 사실을 믿을 수 없나요? 그렇다면 'ed' 라는 명령어의 매뉴얼 페이지를 보시기 바랍니다. 아마 몇 페이지 넘기지도 못하고 'q' 키를 눌러 버릴 겁니다.

    사실 vi 는 아주 편리한 편집기입니다. 제 경험으로는 그 만큼 편리한 편집기는 써본 적이 없습니다. 글쎄요.. 만일 당신이 emacs 라는 편집기를 써본 경험이 있다면 여기에 이견이 있을지 모르겠습니다만, 혹시 MS-DOS 에서 쓰던 EDIT 나 Q-Editor 혹은 그와 유사한 편집기(제가 그러한 부류에서 손을 뗀지 오래돼서 최신 정보에는 어둡군요)만을 써보았다면 제 말을 믿고 vi 에 큰 기대를 걸어도 후회하지는 않을 겁니다. 단지 버클리의 어느 천재가 만들었다는 이유만으로 시답지 않은 편집기가 이렇게 인기를 끌리는 없으니까요.

    vi 의 이름이 VIsual display editor를 뜻한다는 걸 아십니까? 물론, "비쥬얼" 이 없이는 아무것도 안돼는 요즘 세상의 "비주얼" 과는 다른 의미일 겁니다. 당시는 ed와 같은 라인에디터가 일반적이었기 때문에 vi 와 같은 풀 스크린에디터의 등장은 그 자체로도 관심을 끌만 했겠지요. 라인에디터가 얼마나 불편하고 한심한지는 하이텔의 그 구석기 시대적인 편집기를 써 보신 분은 아실 겁니다. 아니면 예전에 MS-DOS 에 들어있던(지금은 어디로 갔나?) EDLIN을 기억하실지 모르겠습니다. 어쨌거나 옛날엔 모두들 그런 걸 잦고 끙끙대며 썼다는 겁니다.

    라인에디터에서 스크린에디터로 사용자 인터페이스가 발전된 만큼 사용상 편리성 면에서 많은 개선이 이루어졌습니다. 더구나 유닉스처럼 텍스트에디터와 포매터가 분리된 환경에서는 텍스트에디터의 비중이 크기 때문에 기능 면에서도 많은 요구가 있게 마련입니다. 윈도우 같은 환경에서 쓰는 워드프로세서 기능의 상당부분을 텍스트에디터가 갖게 되고 vi 도 예외는 아닙니다.

    그럼 본론으로 들어가서 vi 사용법에 대해 이야기해 볼까요?

    우선 vi 명령을 실행시키세요. 그림1과 같은 화면이 보일 겁니다.

    다소 다르더라도 신경 쓰지 마세요. 유닉스에 여러 종류가 있는 것처럼 vi 에도 여러 가지 버전이 있어서 약간씩의 차이가 있습니다. 게다가 앞으로 제가 그려서 보여드리는 vi 는 아주 작은 화면을 쓸 겁니다(크게 해서 지면을 늘이면 원고료가 많아지니 제게는 좋습니다만 ^_^).

    단, 어느 경우든 '~' 문자는 아무 것도 없는 빈줄임을 나타냅니다.

    처음 vi를 실행시키면 당장 무엇을 해야 할지 막막할 겁니다. 마치 한 손에 돌도끼를 든 원시인이 된 기분일지도 모르겠습니다. 이제 vi에서 가장 어려운 명령어를 먼저 가르쳐 드리지요.
     

    :q

     
    라고 입력해 보세요. "엉? 이게 뭐야" 좀 속은 기분인가요? 아니면 낯익은 셸 프롬프트로 돌아가서 안심이 되었는지도 모르겠군요. 눈치 빠른 분은 이게 "quit" 의 약자라는 걸 알아차렸겠지요. 아무것도 아닌 것 같지만, 이미(멋모르고) vi를 실행했던 경험이 있는 초보자라면 이 명령이 '가장 중요하다'는데 공감할 겁니다. 언젠가 리눅스 동호회 게시판에서 vi를 빠져나오는 법을 몰라 시스템을 리부팅했다는 글을 본적이 있습니다. 물론 그렇게 하지 않더라도 얼마든지 품위있게 vi를 끝내는 방법이 있지만, 어쨌거나 어떤 명령어를 처음 쓸 때는 그 명령어를 끝내는 방법을 미리 알아두는 것이 필요하다는 걸 기억하시기 바랍니다. 혹시 다음에 emacs를 배우게되면 이 점을 잊지 마세요(emacs 끝내는 방법은 vi 와는 전혀 다릅니다.) 아니면 또 한번 시스템을 리부팅하게 될테니까요.

    자, 이제 뭔가를 써넣어야겠지요? 지금쯤 한가지 사실을 알아둘 필요가 있겠네요. vi 가 다른 '평범한' 문서 편집기와 비교할 때 가장 특이한 점은 프로그램의 사앹가 '명령모드'와 '입력모드'로 구분 되어있다는 점입니다. 보통의 편집기는 키보드에서 입력되는 문자가 그대로 문서에 포함되지요. 즉, 기본적으로 입력 모드에 있는 겁니다. 이에 반하여 vi는 기본적으로 명령 모드에 있습니다. 키보드에서 입력하는 내용은 문자 하나하나가 vi 에 대한 명령어로 인식됩니다. 이중에 입력 모드로 전환시키는 명령어가 포함되어있으면 그때 비로소 입력모드로 들어가게 되지요. 자, 우선 vi 명령을 다시 실행하세요. 이제 그림 2에 보인 바와 같이 'i' 로 시작하는 내용을 입력해보시기 바랍니다.

      iwhen you're weary, <CR>foolin' small,<Esc>
      when you're weary,
      foolin' small,
      ~
      ~

    입력중에 줄 바꿈을 하려면 '<Enter>' 키를 이용한다는 것까지 설명할 필요는 없겠지요. 명령 모드에서 입력하는 내용을 그림에서는 역상 문자로 나타내기로 하겠습니다. 스크린 안의 역상 문자는 물론 커서를 나타낸 것입니다.(이거 그리느라 무척 애먹었습니다). 'i' 키를 누르는 것만으로는 화면에 아무 변화도 없을 겁니다. 그 이후에 입력하는 내용이 비로소 화면에 나타나겠지요. 이제 명령모드가 뭔지, 또 입력 모드가 뭔지 감이 잡히지요? 'i' 는 '삽입하기(insert)' 명령입니다. 그 이후에 입력되는 키는 모두 문서의 내용으로 간주합니다. 즉, 입력 모드로 전환하는 겁니다. 잠깐, 동료들이 밥 먹으러 가자고 부르는군요. 그냥 두고 가도 되겠지만, 천신만고 끝에 입력한 한 줄짜리 문서를 날려 버릴 위험이 있으니 뭔가 조치를 취해야겠지요.
    아니아니, '<Ctrl>-s' 나 '<Alt>-s'는 소용이 없답니다. 그랬을거면 ':q' 대신에 '<Alt>-x'를 썼겠지요. 편집 중인 문서를 저장하려면 ':q' 만큼이나 그럴 듯한 명령이 있습니다. 그림 3과 같이 입력해 보세요.

                                              :wwords.txt
      ~
      ~
      ~
      :wwords.txt


                                                  <CR>
      ~
      ~
      ~
      "words.txt" 2 lines, 36 characters written

      < 그림3 > 'w' 의 명령 사용법

    물론 ':w'는 '파일에 쓰기(write)' 명령입니다. 뒤에 나오는 'words.txt' 는 파일 이름이니 마음대로 정하시기 바랍니다. 그런데 여기서 명심해야 할 것 한 가지가 있어요. '<Esc>' 키를 누르는 것 말입니다. 이건 입력 모드에서 명령 모드로 돌아가기 위한 겁니다. 사실 현재 상태가 입력 모드인지 명령모드인지 잘 알 수가 없는 경우가 많지요. 만일 명령 모드로 돌아가고 싶다면 아무 때나 '<Esc>' 키를 누르세요. 입력 모드에 있었다면 당연히 명령 모드로 바뀔 테고 원래 명령 모드였다면 그냥 '삑' 하는 벨 소리 한번 내고 말 겁니다.

    현재 상태가 어떤 모드인지 잘 모르신다면 일단 '<Esc>' 키를 눌러 명령 모드로 간 후 다시 시작하시면 됩니다. 단, '삑' 소리를 자주 내면 옆 사람이 짜증을 낼 지도 모르겠네요. 야박한 동료들이라면 쫓겨날지도 모릅니다. 사실 분당 '삑' 소리 회수로 그 사람이 vi를 얼마나 잘 쓰는지 판단할 수 있습니다. 숙달될수록 회수가 줄어드니까요.

    그때까지는 눈치를 좀 보기로 하지요. 자 이제 다른 사람을 위해서 vi를 빠져 나가는게 좋겠지요. 방법을 잊어 버리시지는 않았는지요?(식사는 잘 하셨는지...)

    이제 하던 일을 계속 해볼까요. vi를 다시 실행하기는 해야 하는데, 아까하고는 상황이 좀 다르군요. 이미 만들어져 있는 파일을 열어서 작업을 계속해야 하니까요. 이번에는
     

    vi words.txt

     
    라고 하면 됩니다. 이 정도는 직관으로 아실 수 있겠지요. 이제 해야 할 일은 아까 입력했던 내용 다음에 계속해서 새로운 내용을 추가하는 겁니다. 우선 커서를 문서의 끝으로 옮겨야 하겠네요. 여기에는 상식이 통합니다. 그냥 화살표 키를 써보세요. 커서를 문장의 끝으로 옮겼다면 이제 아까 배운 'i' 명령을 쓸 차례군요. 그런데, 'i' 는 현재 커서의 위치에 문자를 집어 넣고 원래 있던 문자는 뒤로 밀어내지요. 이번 용도에는 잘 맞지 않는군요. 커서의 뒤에 덧붙이는 명령을 써야겠네요. 있다면 말이지요. 이번에는 그림4와 같이 입력해보세요.

      when you're weary,
      feelin' small,
      ~
      ~

      a<CR>tears are in your eyes, <Esc>


      when you're weary,
      feelin' small,
      tears are in your eyes, 
      ~

      < 그림 4 > 'a' 의 명령 사용법

    'a'를 누르면 현재 커서 위치의 문자는 그대로 두고 그 뒤로 커서가 옮겨가지요? 이건 '덧붙이기(append)' 명령을 의미합니다. 이때부터는 입력 모드입니다. 여기까지 입력하고 일단 명령 모드로 돌아오시기 바랍니다.(어떻게?) 이제 겨우 3줄이 되었군요. 지금부터는 자주 저장하는 습관을 들여야 합니다. 그냥
     

    :w


    라고 입력하세요.(물론, 명령 모드에서입니다. 이제 이 말은 더 이상 안 하렵니다.). 파일 이름을 지정하지 않으면 그냥 현재의 이름으로 저장합니다. 번거롭겠지만, 한 번 더 나갔다 들어오죠. 대신 이번엔 다른 방법을 알려 드리겠습니다.(별거 아닙니다)
     

    :wq

     
    라고 해보세요. 쓰고 빠지라는 얘기죠. 아니면
     

    zz

     
    라고 해도 같은 기능을 합니다. 이 경우는 편집 중인 파일의 내용이 수정되었으면 저장한 후 종료하고 그렇지 않으면 그냥 빠져 나옵니다. 지금까지 쓴 명령어 중 일부는 ':' 로 시작되는 걸 알 수 있습니다. 명령모드에서 ':'를 치면 일단 맨 밑줄에 그 내용이 출력되지요. 그래서 이걸 '끝줄 모드(last-line mode)' 라고 따로 구분하는 경우도 있습니다. 사실 이 모드에서 쓰이는 명령어는 'ex' 라는, 또 다른 편집기와 관계있는 것들입니다. 이에 대해서는 다음 기회에 더 자세히 알아보기로 하겠습니다. 여기서는 ':wq' 와 'ZZ'(대문자 Z 두 개)가 비슷한 기능을 수행한다는 점만 알아두시기 바랍니다.

    이쯤 해서 커서를 옮기는 방법에 대해 좀 더 살펴볼까요. 물론 편집하던 문서는 다시 열어 두셨겠지요? 앞서 이미 화살표 키를 이용하면 된다고 했지만, vi 답게 뭔가 별난 방법이 있을 것 같지 않나요? 사실 vi는 일반적으로 쓰는 환경보다 더 열악한 환경에서도 잘 동작하도록 되어있습니다. 화살표 키가 안 듣는 경우에도 vi를 거뜬히 쓸 수 있습니다. 사실 좀 습관이 되면 화살표 키 따위는 쓰지 않게 될 겁니다. 'h', 'j', 'k', 'l' 키를 몇 번씩 번갈아 눌러 보세요. 어떤 키가 어떤 방향인지 외우려고 하지 말고 감으로 익히시기 바랍니다. 저도 위 방향으로 가려면 어떤 키를 눌러야 되느냐고 묻는다면 대답하지 못합니다. 사실은 어떤 키들이 쓰이는지 조차도 외우지는 못합니다만, 화살표 키는 전혀 쓰지 않습니다. vi를 제대로 익히면 모든 명령을 문자-숫자 판만으로 해결할 수 있습니다.

    이번에는 번거롭게 커서를 줄의 맨 끝으로 이동해서 새로운 내용을 추가하는 것 보다 좀더 세련된 방법을 알아보겠습니다. 덧붙이기는 덧붙이기인데 현재 커서 위치 대신 현재 커서가 있는 줄의 끝에 덧붙이는 겁니다. 'j' 키를 이용해서 마지막 줄로 이동한 후(줄의 끝 문자까지 갈 필요는 없습니다.) 그림 5와 같이 입력해 보세요.

      when you're weary,
      feelin' small,
      tears are in your eyes,
      ~
      ~
                A<CR>i'll dry them all.<Esc>


      when you're weary,
      feelin' small,
      tears are in your eyes,
      I'll dry them all.

      < 그림 5 > 'A'의 명령 사용법

    'a' 명령과 'A' 명령이 어떤 차이가 있는지 아시겠지요? 이번엔 마지막 줄에 커서를 두고 그림 6과 같이 입력해 보세요.

      when you're weary,
      feelin' small,
      tears are in your eyes,
      I'll dry them all.
      ~
      ~
               oOh, times get rough, <Esc>


      when you're weary,
      feelin' small,
      tears are in your eyes,
      I'll dry them all.
      Oh, times get rough,

      < 그림 6 > 'o'의 명령 사용법

    이번엔 '<Enter>' 키를 누르지 않았지요. 결과는 같지만. 이 명령은 '새로운 줄 열기(open)'를 의미합니다. 그런데 이 명령에도 대문자 형태의 명령이 있습니다. 일단 명령 모드로 돌아온 후, 이번에는 그림 7을 따라 입력해보세요. 이제 vi 화면에 어느 정도 익숙해지셨을테니 지면 관계상 그림은 가능하면 생략하겠습니다.(사실은 힘들어서 더 못 그리겠습니다.)

      when you're weary,
      feelin' small,
      tears are in your eyes,
      I'll dry them all.
      Oh, times get rough,
      ~
      ~
               OI'm on your side, <Esc>


      when you're weary,
      feelin' small,
      tears are in your eyes,
      I'll dry them all.
      I'm on your side.
      Oh, times get rough,

      < 그림 6 > 'O'의 명령 사용법

    아까는 현재 커서가 있는 줄의 밑에 새로운 줄을 열었던 반면 이번에는 현재 커서가 있는 줄을 아래로 밀어내고 그 자리에 새로운 줄을 열었지요. 아마 대문자라 힘이 좀더 센가 봅니다.

    이제 입력 모드로 가기 위한 명령들을 대충 배운 것 같군요. 한번 정리해 볼까요? 'a', 'i', 'o', 그리고  각각의 대문자 명령어인 'A', 'I', 'O' 가 있지요. 참, 그런데 'I' 에 대해서는 설명이 빠진 것 같군요. 'a'와 'A' 사이의 관계로부터 유추해 보시지요. 아니면 지금 직접 해보세요. 'I'와 'O'의 차이가 무엇일까요? 현재 커서가 있는 줄의 내용을 밀어내고 새로운 내용을 입력받는다는 점은 같은데, 끝에 줄 바꿈이 포함되느냐 안되느냐의 차이가 있지요. 마찬가지로 'A' 와 'o'의 차이점도 생각해보시기 바랍니다.

    자, 이제 제법 문서의 분량이 늘어났군요. 지금부터는 문서를 열어서 'j' 키로 문서의 끝까지 이동하는 것이 귀찮아지기 시작할 겁니다. 혹시 수백 페이지 짜리 문서를 편집할 경우를 상상한다면 아찔할 지도 모르겠군요. 뭔가 한번에 옮겨가는 방법이 있을 법하지요? vi 의 특징 중 하나는 "왠지 있을 것 같은 기능은 어김없이 있다" 는 겁니다.
     

    G


    를 한번 눌러 보시지요. 커서가 어느 위치에 있었건 간에 문서의 마지막 줄의 첫 문자에 가서 대기하고 있을 겁니다. 맨 끝으로 보내는 명령이 있는데 맨 처음으로 보내는 명령이 없을 리 없지요?
     

    1G


    라고 쳐보세요. 이번에는 문서의 첫 줄의 첫 문자에 커서가 옮겨가 있을 겁니다. 'G' 명령 앞에 붙은 숫자는 줄 번호를 나타냅니다. 만일 '3G'라고 하면 당연히 3번째 줄로 커서가 옮겨갑니다. 하지만 여기에도 문제는 있습니다. 지금처럼 몇 줄 안되는 문서야 눈어림으로 몇 번째 줄인지 알 수 있지만 그렇지 않은 경우는 어떻게 하지요? 걱정할 필요 없습니다.
     

    :set nu


    라고 쳐보세요. 모든 줄의 앞에 줄 번호가 매겨질 겁니다. 줄 번호가 편하기는 하지만 때로는 보기에 불편할 수도 있습니다. 줄 번호를 없애려면 그냥
     

    :set nonu

     
    라고 하면 됩니다.

    이제 문서 전체의 어떤 위치로도 커서를 손쉽게 옮길 수 있게 되었군요. 단지 'h', 'j', 'k', 'I', 'G' 와 숫자 키만으로 말이지요.

    그러나 아직 끝나지 않았습니다. vi 의 커서 이동 명령은 매우 정교합니다. 커서 이동 명령을 얼마나 능숙히 쓰느냐가 작업 능률에 큰 영향을 줍니다. 곧 다루겠지만, 커서 이동 명령이 다른 명령과 함께 쓰여서 여러 가지 다양한 기능을 수행할 수도 있습니다. 지금 아무 위치에서나
     

    w


    키를 눌러 보세요. 커서가 한 단어 오른쪽으로 이동할 겁니다. 새 단어의 첫 문자에 위치하게 되지요. 단어(word) 단위로 이동하라는 명령입니다. 당연히 반대로 이동하는 명령도 있어야겠지요. 이번에는
     

    b


    키를 눌러 보세요. 이건 거꾸로(back) 한 단어 이동하라는 명령입니다. 그러면 이들의 대문자 형태, 즉 'W' 와 'B' 는 어떤 기능을 할까요. 구두점에 주의를 기울이면서 한번 시험해 보세요. 커서 이동 명령에는 'e' 라는 것도 있습니다. 'w' 와 기능은 유사한데 단지, 단어의 첫 문자가 아니라 끝(end) 문자에서 멈춘다는 점이 다릅니다. 도대체 무슨 정신으로 이런 것들을 다 구분해서 쓰나 생각하실지 모르겠지만 사람의 습관이란 논리 판단보다 빨리 움직이게 되어있습니다. 커다란 문서하나 열어놓고 아무 생각없이 'w', 'b', 'e', 'W', 'B'를 부지런히 눌러 보세요. 곧 익숙해 질 겁니다. 정 못해 먹겠다 싶으시면 그냥 'w', 'b' 만 쓰시던가요. 한 줄 안에서 커서를 옮기는 일은 꼭 단어 단위로만 가능한 것은 아닙니다. 앞서 문서의 첫 줄과 끝 줄 사이를 오가는 데 'G' 명령을 썼던 것처럼 한 줄의 처음과 끝 사이를 오가는 데도 따로 명령이 있습니다.
     

    ^
    $

     
    를 번갈아 눌러 보세요. '^'대신 숫자 '0'을 써도 됩니다. '^'보다는 '0'이 쓰기 편할 겁니다.('<Shift>'키를 누를 필요가 없으니까) 이제 커서는 적어도 한 줄 안에서는 부처님 손바닥 안의 손오공이 된 셈입니다.

    이번엔 진짜 좀더 큰물에서 놀아봐야겠습니다. 우선, 좀 덩치 큰 문서를 찾아서 열어 볼까요. 아무거나 상관없지만, 우리가 쓰는 것이 리눅스이니 HOWTO 문서를 하나 골라 보도록 하겠습니다. 흔히 쓰는 레드햇 배포본의 경우, '/usr/doc/HOWTO' 디렉토리에 HOWTO 문서들이 모여 있습니다. 다른 배포본을 쓰시는 분들도 어딘가에 있을 테니 찾아보세요(이 분서들이 어디있는지 모른다는 건 리눅스 쓰는 사람으로서 문제가 있는 겁니다.). 그 중에서 가장 기본이 되는 Installation-HOWTO를 보겠습니다. 일단 다음과 같이 홈 디렉토리로 복사를 하지요.
     

    cp /usr/doc/HOWTO/Installation-HOWTO.gz~


    끝의 '~'는 홈 디렉토리를 나타냅니다. 만일 홈 디렉토리가 '/home/arthur' 라면
     

    cp /usr/doc/HOWTO/Installation-HOWTO.gz /home/arthur


    라고 하는 것과 같습니다. 한가지 더, 확장자가 'gz' 인 것은 gzip 이라는 압축 유틸리티로 압축된 데이터라는 뜻입니다. 따라서, Installation-HOTO.gz 가 복사된 디렉토리로 가서
     

    gzip -d Installation-HOWTO.gz
    또는
    gunzip Installation-HOWTO.gz


    라고 하세요. 이젠 준비가 되었군요.

    혹시 리눅스를 쓰고 있으면서 아직 이 문서를 읽어보지 않은 분들은 이번 기회에 잘 읽어보시기 바랍니다. 이건 리눅서라면 기본적으로 알아야 할 유용한 정보를 많이 담고 있으니까요. 이제
     

    vi Installation-HOWTO

     
    라고 하면 문서를 열어볼 수 있겠군요. 기껏 한 화면 안에서 노닐자고 1,294줄 짜리 문서를 연게 아니라는 건 짐작하시겠지요. 1,294 줄인지는 어떻게 알았느냐고요? '<Enter>' 키를 1,194 번 치면 파일 끝에 이르거든요. 한번 해보세요. 흐흐흐. 그게 아니고 화면 맨 밑을 보세요. 파일 이름과 이게 몇 줄짜리 문서인지 나와 있을 겁니다. 명령모드에 있는 동안은 아무때나 '<Ctrl>-g'를 누르면 전체 줄 수와 현재 몇 번째 줄에 있는지를 알 수  있을 겁니다. 이것도 나중에 쓸모가 있으니 잊지 마세요.

    파일의 첫 줄과 끝 줄 사이를 오가는 명령은 아시지요? 그런데 이렇게 큰 문서를 극에서 극으로만 움직이니 재미가 없을 겁니다.
     

    H

     
    를 눌러보세요. 커서가 화면의 첫 줄로 날아가 버릴 겁니다. 이 키는 'high'를 의미합니다. 다음엔 뭘 해볼까요? 'high' 가 있으니 'low' 도 있지 않겠어요? 역시 대문자로
     

    L

     
    를 눌러 보세요. 기대했던 대로지요? 그럼 중간(middle)은 어떨까요?
     

    M

     
    을 눌러 보세요. 'H', 'M', 'L' 은 화면 그대로 이고 커서만 위아래로 이동하는 명령입니다. 그럼, 아예 화면을 옮겨 다니는 명령을 알아보겠습니다.

    vi 에서 화면이란, 터미널이 사용자에게 보여주는 특정 부분을 말합니다. 우리가 처음에 편집하던 짧은 문서는 한 화면에다 보일 수 있지만, 지금 얼어 놓은 파일처럼 큰 파일은 일부분만을 보여 주지요. 만일 현재 화면에 보이지 않는 부분을 보거나 편집하려면 화면을 그 부분으로 옮겨가야만 합니다. 앞서 보았던 'G' 명령도 일종의 화면 이동 명령이라 할 수 있습니다. 여기서 설명 드릴 4가지 명령은 모두 '<Ctrl>'키와 함께 쓰인다는 것을 우선 알아두시기 바랍니다. 앞과 뒤 방향을 의미하는 forward 와 backward, 그리고 위와 아래를 의미하는 up 과 down, 이 네 가지 간단한 단어만 기억하시면 됩니다. 직접 한번 해보세요.
     

    <Ctrl>-f
    <Ctrl>-b
    <Ctrl>-u
    <Ctrl>-d


    잘 보시면 '<Ctrl>-f' 와 '<Ctrl>-b'는 한 화면 단위, 즉 화면이 24줄이라면 24줄 단위로 이동한다는 걸 알 수 있을 겁니다. 반면에 '<Ctrl>-u' 와 '<Ctrl>-d'는 반화면 단위로 움직이지요. 이 외에도 이동하는 방식에 차이점이 있지만, 아마 지금 쓰시는 컴퓨터의 속도가 직접 암산하는 것보다 빠른 정도라면 거의 느낄 수 없을 겁니다(사실 별로 중요하지도 않습니다.). 지금까지 배운 모든 기능들을 이 파일에서 연습해 보시기 바랍니다. 입력 모드 전환과 커서 이동 방법등에 충분히 적응하셨다면 이제 좀더 재미있는 기능들에 도전해 보도록 하겠습니다.

    다시 처음 우리가 편집했던 역작 'words.txt'를 가지고 놀아 봅시다(물론, 위의 Installation-HOWTO 는 반드시 읽어 보셔야 합니다.). 우리가 알고 있는 입력모드 명령은 'a', 'i', 'o' 정도였습니다. 그런데, 편집하다 잘못 입력했을 때는 어떻게 하지요? 그건 간단합니다. 편집하던 파일을 버리고 새로 만들면 되지요. 좋은 방법이긴 한데(?) 그렇다면 아무도 vi를 쓰지 않을 겁니다. 이번엔 왠지 마음에 안 드는 단어 위로 커서를 옮기고
     

    x


    를 눌러 보세요. 방금 당신은 불쌍한 문자 하나를 사형시킨 겁니다. 마음이 무겁다고요? 그럼
     

    u


     를 눌러 보세요. 한번 겁주는 걸로 끝내기로 하지요. 보신 바와 같이 'u'는 명령 취소(undo)를 의미합니다. 요즘 vi는(vi 도 종류가 여러 가지입니다.) 안 그런 경우도 있지만 원래 명령 취소는 한 단계만 지원됩니다. 다시 'u'를 누르면 방금 했던 '명령 취소' 명령이 취소됩니다. 즉, '재시행(redo)' 이 되는 겁니다. 만일 지금 쓰고 있는 vi 가 'u'를 누를 때마다 이전에 수행했던 명령들을 계속 취소한다면 '<Ctrl>-r'을 눌러 보세요. 제대로 된다면 그 vi 는 undo 와 redo를 구분하는 겁니다. 신나게 'x'를 눌러 댔는데 잘 보니 엉뚱한 곳이었네요. 이런 바보짓은 문서 작성 중에 흔히 저지르는 일입니다. 'u' 명령이 여러 단계 들어먹는 vi라면 그만큼 'u'를 눌러 대면 됩니다만, 방금 전 말씀드린 대로 원래의 vi는 그게 안됩니다. 다시 입력모드로 들어가서 새로 치는 수밖에요. 뭐가 나쁘면 팔다리가 고생한다더니 어쩌고 궁시렁대면서 말이지요. 잠깐, 이 경우에도 간단한 해결 방법이 있습니다. 대문자로
     

    U


    를 눌러 보세요. 그러면 그 줄에 대해서 행해졌던 편집 내용이 모두 취소됩니다. 단, 편집한 후 커서를 다른 줄로 옮겨가면 정말로 영영 끝나는 겁니다. 실수를 발견했을 때 바로 써야 합니다.

    그러나 한참을 편집하다가 갑자기 마음이 바뀌었을 경우는 어떨까요? 물론 이제까지 쳐 넣은게 아깝기는 하겠지만, 미련 없이 버리겠다면? 그렇죠, 그냥 빠져 나오면 되지 않겠어요? 거 쉽다.
     

    :q


    잉? No write since last change (use! to override), 이게 뭔 소리여? 호락호락 나가 주지는 않겠다는 말 같은데, 또 '!'를 쓰라는 말은 무엇입니까? 말인즉슨 수정한 내용을 저장하지 않았으니 그냥은 못나가겠다 이겁니다. 많이 봐주는 척 하는군요. 봉황의 깊은 뜻을 모르고... 쯧. 뭐, 하라는 대로합시다.
     

    :q!


    됐지요? 이럴 땐 좀 귀찮기도 하지만, ':q'라고 친다고 아무 때나 그냥 빠져 나오는 것보다는 나을 겁니다(생각해보세요. 그랬다가는 땅을 치고 후회하는 일이 하루에도 몇 번씩 생길 겁니다). 대신 '!'를 써서 '잔말말고 시키는대로 하라'고 세게 나갈 수 있습니다(즉, 여기서는 '알았으니까 그냥 나와, 임마', 이런 뜻입니다.). 그러고 보니 'u' 명령도 대문자의 형태와 쌍을 이루는군요. 'x'라고 없을 리 없지요. 이제
     

    X

    라고 명령해 보세요. 뭔가 없어지긴 했는데 어느 놈인지 잘 분간이 안된다고요? 이번에는 커서가 위치한 곳의 바로 앞 문자가 지워진 겁니다. 그러면서 커서와 커서가 있던 문자 이후의 내용이 한 칸 씩 당겨진 것입니다.

    이제 쓰고 지우는 방법을 익혔으니 사실상 문서의 수정이 가능하게 되었네요. 하지만 지우고 쓰는 걸 한번에 하는 명령은 없을까요. 고치기 명령 말입니다. 있을 법한 명령은 있게 마련이라는 말 기억나시죠? 이제 고치기(change) 명령 'c' 에 대해 알아보기로 하지요. 이 명령은 적용 범위를 나타내는 문자와 함께 쓰입니다.
     

    cw


    를 써 보세요. 아까 'w'와 'b'가 어떻게 쓰였는지 생각해 보세요. "아하, 그렇구나" 하시게 될 겁니다. 'cw'의 경우, 현재 커서가 있는 위치에서 단어 끝까지를 고칠 대상으로 설정합니다(그럼 'cb'는 무엇일까요? 'c0' 은? 'c$'는?).  이제 새로운 내용을 입력하세요. 원하는 내용이 다 입력되었으면 다시 명령 모드로 돌아오면 됩니다(어떻게?).  이건 'x' 명령을 여러 번 쓰고 다시 입력 모드로 들어가서 문서 편집은 할 수 있습니다만, 아는 만큼 편하게 쓰겠지요. 사람이 어디 단어 단위로만 잘못을 저지르겠습니까? 때로는 한 줄을 몽땅 바꿔 버리고 싶을 수도 있지요.
     

    cc


    를 써보시죠. 보통 vi에서 같은 소문자 두 개로 이루어지는 명령은 커서가 있는 줄 전체에 대해 적용됩니다. 즉, 이 경우에는 한 줄 전체를 고치게 됩니다. 원래의 내용이 없어지면서 빈 줄이 하나 나타나는데 거기에 입력하면 됩니다. 내용을 다 넣은 후에는 '<Esc>' 키로 마치면 됩니다. 하는 김에 한 가지 더 할까요? 커서를 줄의 가운데쯤으로 대충 옮겨놓고
     

    C

     
    를 눌러 보세요. 현재 커서 위치에서 줄의 끝까지 고칠 수 있게 됩니다. 좀 순서가 바뀐 것 같지만, 한 문자만 고치는 경우를 생각해 봅시다. 여러 문자 또는 단어를 고치는 경우라면 입력하는 내용이 어디에서 끝날지 모르기 때문에 '<Esc>' 키를 눌러야 입력모드를 빠져 나오게 되어있습니다. 만일 한 문자만 바꾸려 한다면 입력 후 바로 명령 모드로 돌아가게 하는 것이 편하겠지요. 물론 그런 명령어가 따로 있습니다.
     

    r


    을 입력한 후, 한 문자를 입력해 보세요. 현재 커서 위치에 있는 문자가 새로 입력한 문자로 바꿔치기(replace) 될 겁니다. 물론 입력모드에서 자동으로 빠져 나와 있을 겁니다. 이번엔
     

    R


    을 이용해 보세요. 이건 좀 다르게 동작합니다. 문자를 바꿔치기하고 커서를 하나 다음 누자 위로 이동한 후 입력 모드를 빠져나오지 않고 대기합니다. 다시 문자를 입력하면 새로운 커서 위치의 문자를 바꿔치기 합니다. 즉, 커서가 진행하면서 입력하는 내용으로 원래 있던 내용을 계속 덮어쓰게 됩니다. 멈추려면 역시 '<Esc>' 키로 입력모드를 빠져 나오면 됩니다. 한 문자를 여러 문자로 고치는 경우는 어떨까요?
     

    s


    명령을 쓸 경우에는 커서가 있는 위치의 한 문자를 지우고 입력 모드로 들어갑니다. 입력 모드를 빠져 나올 때까지 입력된 내용으로 원래의 한 문자를 대치(substitute) 하게 되는 것이지요.

    이쯤에서 퀴즈하나 내볼까요? 한 줄로 이루어진 내용을 두 줄로 분리하려면 어떻게 하나요? 이건 너무 쉽지요. 적당한 위치의 공백 문자로 가서 'r'을 누른 후 '<Enter>'를 치면 되니까요. 만일 공백문자가 아닌 곳에서 나누려면 그냥 'i'를 누른 후 '<Enter>'를 치고 '<Esc>' 키로 명령 모드로 돌아오면 될테고요. 그럼 반대는 어떨까요? 두 줄로 되어있는 내용을 한 줄로 만들려면? 이것도 이미 배운걸로 됩니다. 히히히, 뻥입니다요. 고민 많이 하셨어요? 사실은 두 줄을 하나로 잇는(join) 명령은 따로 있습니다.
     

    J


    라고 쳐보세요. 어떤 일이 일어나나.

    이번에는 'x'를 때려 대며 하나하나 지우는 게 감질나서 못해먹겠다는 통큰 분을 위해 좀 과격한 방법을 소개하겠습니다. 사실 엄마 몰래 오락실에서 정신없이 눌러대던 초등학교 시절(지금도 그러신다고요?)의 추억에 잠기는 것도 괜찮을 것 같지만, 아무래도, 그런 기분은 안 나지요. 자, 이제 다시 한면 가엾은 사형수를 고르세요. 다섯 번째 줄이 좋을까요? 아니면 여섯 번째?
     

    dd


    아까 말씀드렸지요? 보통 같은 소문자 2개로 이루어진 명령은 커서가 있는 줄 전체에 적용된다고. 이 명령으로 우리는 한 줄 전체를 깨끗이 날려(delete) 버렸습니다. 이 정도 익혔으면 이제 뭔가 감각이 생겼을 것 같은데, 혹시
     

    D


    가 어떤 결과를 가져올지 짐작이 가시나요? 아까 'cc' 와 'C'의 경우를 생각해 보세요. 현재 커서의 위치에서부터 문장 끝까지의 내용을 지워 버릴 거라는 정도의 통밥은 모두 같고 계시리라 믿습니다. 'dw'는 언급할 필요도 없을 것 같고 좀더 큰 기술을 걸어 보지요. 'd^' 와 'd$'는 그래도 한 줄 안에서 저지르는 것이니까 좀 싱겁지요.
     

    dG


    라고 해보세요. 현재 커서가 있는 줄부터 끝까지 한꺼번에 보내 버렸습니다(왜 'G'냐고 묻지 마세요. 저 화냅니다.) 그럼 현재 줄부터 처음까지 모두 없애는 건 어떻게 할까요. 이번엔 "진짜로"지금까지 배운 걸로 해결할 수 있습니다. 바로
     

    d1G


    입니다. 'c'도 똑같은 방법으로 쓸 수 있습니다. 직접 확인해 보세요. 쓰고, 지우고, 고치고... 이제 모두 끝난 것 같지요. 그러나 아직도 남아 있습니다. 사실 가장 유용한 기능 중 하나입니다. 복사 및 붙이기 기능입니다. 이런 꺼벙해 보이는 편집기에 그런 기능까지 있을까 하고 놀라실지 모르지만, 이건 vi 의 가장 기본적인 기능 중 하나입니다.

    이게 뭘까요. 바로 복사하기(yank) 기능입니다. 이 명령을 내리면
      

    yy


    현재 커서가 있는 줄의 내용이 모두 vi 의 내부 버퍼에 임시 저장됩니다. 매킨토시나 윈도우의 클립보드를 연상하시면 됩니다. 왜 줄의 내용 전체인지 다시 설명해 드릴 필요 없겠지요? 'yw'나 'y0', 'y$' 같은 명령이 가능하다는 것을 말씀드리면 오히려 이해가 쉽겠네요. 다시 한번 'c' 와 'd' 명령을 상기하고 이 'y' 명령과 비교해 보시기 바랍니다. 물론 내부 버퍼는 보이지 않습니다. 따라서 'y' 명령과 비교해 보시기 바랍니다. 물론, 내부 버퍼는 보이지 않습니다. 따라서 'y' 명령만으로는 도대체 vi 이놈이 무슨 짓을 했는지 알 수 없습니다. 궁금하시죠? 이제 커서를 적당한 곳에 옮긴 후,
     

    p


    라고 해보세요. 버퍼에 들어가 있던 내용이 그대로 붙여질(put)겁니다. 줄의 일부를 복사해 두었다면 커서가 있는 문자의 뒤에 붙여지고, 줄 전체를 복사해 두었다면, 커서가 있는 줄의 밑에 붙여질 겁니다. 여기서 잠깐 전에 배웠던 명령 몇 개를 다시 봅니다. 'i'는 커서가 있는 문자 앞에, 'a'는 커서가 있는 문자의 뒤에 내용을 입력했지요. 'O'는 커서가 있는 줄의 위에, 'o'는 커서가 있는 줄의 밑에 새로운 줄을 열었습니다. 'p'도 유사한 특성을 갖는데,
     

    P

     
    는 문자를 붙여 넣는 경우 커서가 있는 문자의 앞에, 줄을 붙여 넣는 경우 커서가 있는 줄의 위에 붙여 넣게 됩니다. 이렇게 버퍼를 쓰는 명령은 사실 이미 한가지 알고 있었습니다. 바로 'd' 명령입니다. 예를 들어 'dd'를 하면 커서가 있는 줄이 삭제되지만, 그 내용은 버퍼에 보관됩니다. 'y' 와 'd' 의 차이는 마치 윈도우용 응용 프로그램에서 일반적으로 쓰이는 단축키인 '<Ctrl>-c' 와 '<Ctrl>-x' 의 차이와 같습니다. 새로 'y' 나 'd' 명령이 쓰이면 버퍼에 있던 내용이 바뀐다는 점도 윈도우의 클립보드와 비슷하지요. 따라서 복사하기 및 붙이기 기능을 자주 이용할 때는 버퍼의 내용에 주의해야 합니다.

    이제 이러한 것들을 좀 응용해 보도록 하지요. 만일 3,4,5번째 줄을 6번째 다음으로 옮기려면 어떻게 해야 할까요? 우선 3번째 줄에서 'dd' 한 후(한 줄 지웠으니까) 5번째 줄로 가서 'p'를 누르고, 다시(원래는 4번째 줄이었던) 3번째 줄로 가서 'dd' 한 후 5번째 줄로 가서 'p'를 누르고, 다시(원래는 5번째 줄이었던) 3번째 줄로 가서 'dd' 한 후 5번째 줄로 가서 'p'를 누르면 됩니다.

    됐나요? 그런데 좀 복잡하네요. 더 간단히 할 수 있을 것도 같은데.

    vi 의 아주 유용한 기능 중 하나가 어떤 명령어는 앞에 번호를 붙임으로써 수행회수를 지정할 수 있다는 겁니다. 이를 이용해서 아까 했던 과정을 다시 해 볼까요? 우선 3번째 줄에서 '3dd'를 합니다. '3dd'는 하나의 명령입니다. 'dd'를 3번 수행하는 것이 아닙니다. 따라서 이렇게 하면 3줄의 내용이 한꺼번에 버퍼에 들어가게 됩니다. 이제 바로 'p'를 누르면 아까와 같은 결과를 얻게 되지요.

    훨씬 간단하지요? 이처럼 수행회수를 지정하는 다른 예를 들어볼까요? '2yy'는 커서가 있는 줄을 포함해서 두 줄의 내용을 버퍼에 복사하라는 명령입니다. '5x'는 커서가 있는 문자부터 5개의 문자를 지우라는 명령이지요. 그럼 '3s'는 무엇일까요? 커서가 있는 위치의 문자부터 3개의 문자를 지운 후 입력모드로 전환합니다. '<Esc>' 키에 의해 명령 모드로 돌아올 때까지 입력된 내용이 원래 있던 3개의 문자를 대치하게 됩니다. '7r'은 7개의 문자 각각을 모두 다음에 입력하는 하나의 문자로 바꿉니다. 예를 들어 '7r0'라고 입력하면 현재 커서가 있는 위치부터 7개의 문자를 7개의 '0' 즉, '0000000'으로 바꿉니다. 이런 방법은 내용을 입력하거나 고칠 때만 적용되는 것이 아닙니다. '5j' 나 '7k'가 어떻게 적용되는지 직접 해보세요. 그 밖의 커서 이동 명령에도 적용해서 연습해 보시기 바랍니다.

    한참을 떠들어대니 힘드는군요. 이제 한가지만 더 말씀드리고 끝내야겠습니다. 버퍼가 하나 뿐이라 불편하지 않습니까? 문서를 죽 훑어 보면서 두 가지 문자열을 적절한 곳에 삽입하는 작업을 해야 한다고 가정합시다. 두 개의 버퍼에 두 개의 문자열을 하나씩 넣어 두고 필요한 곳마다 'p'명령을 쓰면 참 간단할 것 같지요. 사실 vi 에는 앞서 사용한 버퍼 외에 26개의 별도의 버퍼가 제공됩니다. 각 버퍼에는 이름이 주어져 있고 각 버퍼의 내용들은 서로 영향을 주지 않습니다. 이름은 영어 알파벳 a부터 z 까지 입니다. 그래서 26개입니다.(맞나요?)

    사용방법은 간단합니다. 그냥 'y' 나 'd' 명령을 쓰기 직전에 '"a' 와 같이 버퍼 이름을 지정하면 됩니다. 두 번째 버퍼를 쓰려면 '"b' 라고 하면 됩니다. 각 버퍼에 있는 내용을 붙여 넣을 때도 같은 방법으로 버퍼를 지정하면 됩니다. 예를 들어 '"a2yy' 라고 하면 현재 커서가 있는 줄을 포함해서 2줄을 버퍼 a 에 넣어 두고, 이어서 '"by$' 라고 하면 현재 커서가 있는 위치부터 줄의 끝까지의 내용을 버퍼 b 에 넣어 둡니다. '"' 문자를 버퍼 이름과 함께 써서 특정 버퍼를 지정한다는 겁니다. 아시겠지요? 이제 적당한 위치에서 '"ap' 라고 하면 버퍼 a 에 저장된 2줄의 내용을 현재 커서가 있는 줄 다음에 붙여 넣고 다시 적당한 위치에서 '"bP' 라고 하면 버퍼 b 에 저장된 내용을 현재 커서가 있는 문자의 뒤에 붙여 넣게 됩니다. 이 버퍼의 사용은 여러 문서를 동시에 편집할 때에도 요긴하게 쓰이니 반드시 기억하시기 바랍니다. 모든 게 그렇지만 말로 듣고 이해하는 것만으로는 부족합니다. 자, 그럼 다음 그림을 보고 따라해 보세요.

      when you're weary,
      feelin' small,
      tears are in your eyes,
      I'll dry them all.
      I'm on your side.
      Oh, times get rough,
      and pain is around,

      "ayw~0jj"aPj$4h"byejjbb"aPje"bp


      when you're weary,
      feelin' small,
      when tears are in your eyes,
      I'll dry them all.
      I'm on your side.
      Oh, when times get rough,
      and pain is all around,

      < 그림 8 > 지정된 버퍼 사용법

    마치 무슨 암호를 나열해 놓은 것 같지요. 무슨 뜻인지도 모르고 보고 베낀다면 무척 헛갈리겠지만 그 의미를 알고 쓴다면 역시 별거 아닙니다. 사실, 처음 나온 명령어도 하나 있으니 유의해서 보세요(뭘까요?). 우선 한번 보고 더듬더듬 따라한 후, 다음에는 각 명령어의 의미를 따져가면서 직접 해 보세요. '감'으로 하라는 말 기억나세요?(제다이의 기사처럼, 눈을 감고 'force'를 쓰세요.)

    다음 기회에는 여러 문서를 동시에 열어놓고 편집하는 방법을 비롯한 파일 다루기와 문자열 검색 및 대체, vi 에서 ex 명령어 사용하기와 같은 더 복잡한 내용을 다루기로 하겠습니다. 참, 숙제 한가지. '.' 가 명령 모드에서  쓰이면 무슨 역할을 하는지 알아보세요. "문장의 끝을 나타내는 마침표입니다." 이런 대답하는 분 없기를 바랍니다. ^_^




▲ top

home으로...