範囲 + 動作、そして繰り返しの三段階
한국어 원문으로 표시합니다.
한 줄 요약
ex 명령은 전부 범위 + 동작 구조다. 그리고 반복에는 세 단계가 있다 - .(마지막 편집 반복), 치환(패턴이 규칙적일 때), 매크로(절차가 필요할 때).
왜 이게 필요했나
로그 파일에서 특정 조건의 줄만 남기고, IP 를 마스킹하고, 컬럼 하나를 지워야 한다. sed 와 awk 로 파이프라인을 짤 수도 있다. 하지만 결과를 눈으로 보면서 한 단계씩 확인하고 되돌릴 수 있다는 점에서 편집기 안에서 하는 편이 나을 때가 많다. 특히 정답을 모르고 탐색하며 다듬어야 하는 작업이 그렇다.
문제는 대부분의 사람이 vim 을 "한 글자씩 고치는 도구"로만 쓴다는 것이다. 500줄에 같은 수정을 해야 할 때 손으로 500번 하거나, 아예 vim 을 포기하고 다른 도구를 찾는다. 그 사이에 있는 층이 바로 치환과 매크로다.
어떻게 동작하나
ex 명령의 구조부터 통일한다.
| 범위 | 뜻 |
|---|---|
:5 |
5번째 줄 |
:5,10 |
5~10번째 줄 |
:% |
파일 전체 (= 1,$) |
:. |
현재 줄 |
:'<,'> |
Visual 로 선택한 영역 |
여기에 동작이 붙는다. s/찾을것/바꿀것/플래그 가 치환, g/패턴/명령 이 "패턴에 맞는 줄마다 명령 실행"이다.
꼭 알아야 할 세 가지 함정.
g플래그를 빼면 줄마다 첫 번째 매치만 바뀐다.:%s/old/new/와:%s/old/new/g는 다른 명령이다.:g와:v는 반대다.:g/ERROR/d는 ERROR 가 든 줄을 지우고,:v/ERROR/d는 ERROR 가 없는 줄을 지운다. 로그에서 원하는 것만 남길 때는:v다.- 후방참조를 쓰면 매치의 일부만 살릴 수 있다. 괄호로 묶은 부분을
\1,\2로 되부른다. 매치 전체는&다.
매크로의 정체는 생각보다 단순하다. qa 로 기록을 시작해 키를 누르고 q 로 끝내면, 그 키 입력들이 문자열 그대로 레지스터 a 에 저장된다. yank 와 매크로가 같은 a~z 공간을 쓰는 것도 그래서다. @a 는 그 문자열을 다시 입력하는 것뿐이다.
이 사실을 알면 두 가지가 따라온다. 매크로를 :reg a 로 들여다볼 수 있고, "ap 로 꺼내 편집한 뒤 "ayy 로 다시 저장할 수도 있다. 실습에서 매크로를 파일로 저장해 제출하는 것도 같은 원리다.
반복 가능한 매크로의 설계 원칙 세 가지가 있다. 이걸 모르면 매크로가 두 번째 줄에서 어긋난다.
- 시작점을 절대 고정한다. 매크로 첫 키를
0(줄 맨 앞)으로 두면 커서가 어디 있든 같은 곳에서 시작한다. - 이동은 상대적으로.
f,(다음 쉼표로) 처럼 내용 기준으로 움직여야 줄마다 길이가 달라도 동작한다. - 마지막에 다음 대상으로 넘어간다.
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)도 여기서 배운다.