LabHub
배우기 러닝패스 코스

vimとtmux

範囲 + 動作、そして繰り返しの三段階

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

한 줄 요약

ex 명령은 전부 범위 + 동작 구조다. 그리고 반복에는 세 단계가 있다 - .(마지막 편집 반복), 치환(패턴이 규칙적일 때), 매크로(절차가 필요할 때).

階層図: 범위 + 동작・결과를 눈으로 보면서 한 단계씩 확인하고 되돌릴 수 있다・ex 명령의 구조・꼭 알아야 할 세 가지 함정.

왜 이게 필요했나

로그 파일에서 특정 조건의 줄만 남기고, IP 를 마스킹하고, 컬럼 하나를 지워야 한다. sed 와 awk 로 파이프라인을 짤 수도 있다. 하지만 결과를 눈으로 보면서 한 단계씩 확인하고 되돌릴 수 있다는 점에서 편집기 안에서 하는 편이 나을 때가 많다. 특히 정답을 모르고 탐색하며 다듬어야 하는 작업이 그렇다.

문제는 대부분의 사람이 vim 을 "한 글자씩 고치는 도구"로만 쓴다는 것이다. 500줄에 같은 수정을 해야 할 때 손으로 500번 하거나, 아예 vim 을 포기하고 다른 도구를 찾는다. 그 사이에 있는 층이 바로 치환과 매크로다.

어떻게 동작하나

ex 명령의 구조부터 통일한다.

범위
:5 5번째 줄
:5,10 5~10번째 줄
:% 파일 전체 (= 1,$)
:. 현재 줄
:'<,'> Visual 로 선택한 영역

여기에 동작이 붙는다. s/찾을것/바꿀것/플래그 가 치환, g/패턴/명령 이 "패턴에 맞는 줄마다 명령 실행"이다.

꼭 알아야 할 세 가지 함정.

  1. g 플래그를 빼면 줄마다 첫 번째 매치만 바뀐다. :%s/old/new/:%s/old/new/g 는 다른 명령이다.
  2. :g:v 는 반대다. :g/ERROR/d 는 ERROR 가 든 줄을 지우고, :v/ERROR/d 는 ERROR 가 없는 줄을 지운다. 로그에서 원하는 것만 남길 때는 :v 다.
  3. 후방참조를 쓰면 매치의 일부만 살릴 수 있다. 괄호로 묶은 부분을 \1, \2 로 되부른다. 매치 전체는 & 다.

매크로의 정체는 생각보다 단순하다. qa 로 기록을 시작해 키를 누르고 q 로 끝내면, 그 키 입력들이 문자열 그대로 레지스터 a 에 저장된다. yank 와 매크로가 같은 a~z 공간을 쓰는 것도 그래서다. @a 는 그 문자열을 다시 입력하는 것뿐이다.

이 사실을 알면 두 가지가 따라온다. 매크로를 :reg a 로 들여다볼 수 있고, "ap 로 꺼내 편집한 뒤 "ayy 로 다시 저장할 수도 있다. 실습에서 매크로를 파일로 저장해 제출하는 것도 같은 원리다.

반복 가능한 매크로의 설계 원칙 세 가지가 있다. 이걸 모르면 매크로가 두 번째 줄에서 어긋난다.

  1. 시작점을 절대 고정한다. 매크로 첫 키를 0(줄 맨 앞)으로 두면 커서가 어디 있든 같은 곳에서 시작한다.
  2. 이동은 상대적으로. f,(다음 쉼표로) 처럼 내용 기준으로 움직여야 줄마다 길이가 달라도 동작한다.
  3. 마지막에 다음 대상으로 넘어간다. j 로 다음 줄에 내려놔야 10@a 로 반복할 수 있다.

대문자 레지스터는 덧붙이기다. :g/prod/y A 는 prod 가 든 모든 줄을 레지스터 a 에 차곡차곡 쌓는다. 소문자 a 로 쓰면 매번 덮어써서 마지막 줄만 남는다. 흩어진 줄을 한곳에 모으는 관용구가 여기서 나온다.

현장에서 만나는 모습

개인정보 마스킹. 로그를 공유해야 하는데 IP 마지막 옥텟은 지워야 한다. 후방참조 치환 한 줄이면 파일 전체가 정리된다.

설정 파일 일괄 주석. 스테이징 항목만 잠시 꺼야 할 때 :g/staging/normal I# 한 줄이면 된다. :normal 은 각 줄에서 Normal 모드 키를 실행하라는 뜻이라, 줄 필터와 매크로를 결합하는 다리 역할을 한다.

매치 개수만 세기. :%s/패턴//gn 은 아무것도 바꾸지 않고 "N개 매치, M줄"만 알려 준다. 치환하기 전에 사정거리를 확인하는 안전장치다.

반복을 없애는 세 가지 손

vim 에서 속도를 만드는 것은 단축키의 수가 아니라 같은 편집을 반복하지 않는 방법이다. 셋만 손에 익히면 대부분이 끝난다.

. 은 마지막 변경을 반복한다. 그래서 편집을 반복 가능한 한 덩어리로 만드는 습관이 중요하다. ciw새이름<Esc> 처럼 한 번에 끝나는 형태로 고쳐 두면, 다음 자리에서는 n. 만 누르면 된다.

/oldName<CR>      찾는다
ciwnewName<Esc>   첫 자리를 고친다
n.                다음 자리로 가서 같은 것을 반복

일치하는 곳을 눈으로 보면서 고를 수 있으므로, 전부 바꾸면 안 되는 경우:%s 보다 낫다.

치환은 범위와 확인이 핵심이다.

:%s/\vold_(\w+)/new_\1/gc

\v 는 정규식을 다른 언어와 비슷하게 만들어 백슬래시를 줄여 준다. c 는 자리마다 확인을 묻는다. 범위는 %(전체) 말고도 :'<,'>(선택 영역), :.,+10(현재 줄부터 10줄), :g/pattern/s/.../.../(조건에 맞는 줄만)로 좁힌다.

:g 는 치환보다 넓게 쓴다. "패턴에 맞는 줄에 명령을 실행" 이므로 지우기, 옮기기, 모으기가 다 된다.

:g/^\s*#/d          주석 줄을 전부 지운다
:g/TODO/t$          TODO 줄을 파일 끝에 모은다
:v/error/d          error 가 없는 줄을 지운다(v 는 g 의 반대)

매크로는 . 으로 안 되는 여러 단계를 담는다. qa 로 녹화를 시작하고, 한 줄에 할 일을 다 한 뒤 q 로 멈춘다. @a 로 한 번, 100@a 로 백 번 돌린다.

끝까지 안전하게 돌게 만드는 요령이 있다. 매크로 마지막에 j0 를 넣어 다음 줄 맨 앞으로 이동하게 하면 위치가 어긋나지 않는다. 그리고 더 처리할 줄이 없으면 매크로가 실패하도록 만들면, 100@a 를 눌러도 파일 끝에서 저절로 멈춘다. /pattern<CR> 을 매크로 안에 넣는 것이 그 역할을 한다.

되돌리기는 나무다. 실수로 매크로를 100번 돌렸다면 u 를 100번 누르는 대신 :earlier 1m 으로 1분 전 상태로 간다. :undolist 로 갈래를 보고 :undo <번호> 로 특정 상태로 갈 수도 있다.

다음 실습에서 할 것

두 개의 실습이 이어진다. 먼저 vim-power 에서 로그 파일을 대상으로 검색·치환·줄 필터를 ex 스크립트로 만들어 제출하고, 이어지는 vim-macros 에서는 매크로를 파일에 저장해 채점기가 레지스터에 넣고 실행해 보게 한다. ESC 문자를 파일에 직접 넣는 방법(Ctrl-V 다음 Esc)도 여기서 배운다.