본문 바로가기
C.W.K.
Stream
Lesson 04 of 04 · published

Shell 명령과 global 명령

~14 min · vim, shell, global, advanced-substitute

Level 0갇힌 자
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

buffer를 아무 Unix 도구에나 흘려보내기

Vim이 셸과 워낙 깊이 붙어 있어서 텍스트 처리 작업 상당수는 plugin이 필요 없어. buffer를 sort, jq, awk, python 뭐든지에 통과시키고 결과를 도로 받아오면 되거든. 이미 알고 있는 Unix 도구 전부의 앞단이 Vim이 되는 셈이야.

셸을 부르는 세 가지 방식

  • :!cmd — 셸 명령을 실행하고 결과만 보여줘 (buffer는 안 건드려).
  • :r !cmd — 셸 명령을 실행하고 결과를 커서 아래에 끼워 넣어.
  • :%!cmd — buffer 전체를 명령에 통과시키고 결과로 갈아끼워. :'<,'>!cmd는 Visual로 고른 범위에만 같은 일을 해.

한 줄짜리 결정타들

:%!sort는 파일을 정렬해. :%!sort -u는 정렬하면서 중복까지 걸러내고. :%!python -m json.tool은 JSON을 예쁘게 펴주고, :%!jq .는 JSON을 다시 포맷하면서 유효한지도 검사해줘. :%!sed 's/foo/bar/g'는 sed에 익숙한 사람용이고, :'<,'>!sort는 고른 범위만 정렬해.

:% 토큰

:%!cmd, :%s/..., :%y에서 %는 언제나 파일 전체야. 다른 범위 토큰도 있어. .는 지금 줄, $는 마지막 줄, 'a,'b는 mark a부터 mark b까지, '<,'>는 Visual 선택이야.

Global 명령

:g는 Vim에서 가장 강력한데 가장 안 쓰이는 명령 중 하나야. 패턴에 걸리는 모든 줄에 명령을 실행해. 반대 짝인 :v (또는 :g!) 는 걸리지 않는 줄에 실행하고. :normal과 붙이면 걸러낸 줄 묶음에만 Normal mode 동작을 걸 수도 있어.

:g는 찾아서-무엇이든-하는 명령이야. :%s가 찾아서 바꾸기라면 :g는 찾아서 아무거나 하기야. :g/pattern/cmd가 손에 붙으면, 남들이 grep 떠놓고 손으로 고치고 있는 리팩터링 기회가 눈에 보이기 시작해.

고급 치환 레시피

캡처 그룹을 쓰면 치환이 프로그래밍이 돼. \v (very-magic) 까지 얹으면 문법이 드디어 읽을 만해지고. 자주 쓰는 것들이야.

  • 단어 두 개 자리 바꾸기: :%s/\v(\w+) (\w+)/\2 \1/g.
  • 단어마다 첫 글자 대문자로: :%s/\v(\w+)/\u\1/g.
  • 걸린 부분 통째로 대문자로: :%s/.*/\U&/.
  • 걸린 부분을 괄호로 감싸기: :%s/\v(\d+)/[\1]/g.

Code

셸 명령 실행·vim
:!ls -la              " ls 실행, 출력 표시
:!python %            " 현재 파일 Python 으로 실행
                      " (% 가 현재 파일명으로 확장)
:r !date              " date 출력 커서 아래 insert
:r !curl -s https://api.github.com/zen   " 어떤 URL 출력이든
:!git diff %          " 현재 파일 diff
외부 도구 통과·vim
:%!sort                       " 파일 전체 정렬
:%!sort -u                    " 정렬 + 중복 제거
:%!python -m json.tool        " JSON pretty-print
:%!jq .                       " JSON 포맷 + 검증
:%!awk '{print NR, $0}'       " 라인 번호 prepend
:'<,'>!sort                  " visual 선택 정렬
:'<,'>!fmt -w 80              " 선택 80 컬럼으로 reflow
Global 명령·vim
:g/pattern/d                  " 매치 모든 라인 삭제
:v/pattern/d                  " 매치 안 되는 모든 라인 삭제
:g/^$/d                       " 모든 빈 라인 삭제
:g/TODO/normal A ;            " 모든 TODO 라인에 ' ;' append
:g/pattern/t$                 " 매치 라인을 파일 끝으로 복사
:g/pattern/m0                 " 매치 라인을 위로 이동
:g/pattern/normal @a          " 매 매치에 매크로 'a' 실행
:g/^def /print                " 'def' 로 시작하는 모든 라인 print
Capture-group substitution·vim
:%s/\v(\w+) (\w+)/\2 \1/g       " 인접 두 단어 swap
:%s/\v(\w+)/\u\1/g               " 매 단어 첫 글자 대문자
:%s/.*/\U&/                          " 매 라인 대문자
:%s/.*/\L&/                          " 매 라인 소문자
:%s/\v(\d+)/[\1]/g                " 매 숫자 [ ] 로 wrap
:%s/\v(\w+)\.(\w+)/\2.\1/g     " 점 주변 부분 swap

External links

Exercise

텍스트 파일을 열고 순서대로 해봐. (1) :%!sort로 파일 전체를 정렬하고 u로 되돌리기. (2) JSON 파일을 :%!python -m json.tool에 통과시켜 포맷하기. (3) :g/^$/d로 빈 줄 전부 지우기. (4) :g/TODO/d로 TODO가 든 줄 전부 지우기. (5) 이름-성 쌍이 늘어선 목록에 :%s/\v(\w+) (\w+)/\2 \1/g로 순서 뒤집기. 단계마다 다른 종류의 초능력처럼 느껴져야 정상이야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.