-1,10 +1,9 |
(DeleteMe 강좌 형식으로 적어 보려 했는데.. 막상 하려니 귀찮아 죽겠네.. 암튼 현재 작업 중.. 언제 끝날 지 모름. :-) |
흔히 접할 수 있는 한글로 된 vi 도움말 문서들 중에, vi 에서 얼마나 자유자재로 문자열 치환이 가능한지 상세하게 설명한 문서를 찾지 못했다. 사실 없어서 못 찾은 게 아니라 본인이 게을러서 제대로 안 찾아봤을 가능성이 높지만... 지금까지 본 문서들은 가장 기초적인 정규 표현식의 예만 몇 개 들어놓고는 끝이었다. KLDP 에 있는 [http://kldp.org/KoreanDoc/html/Vim-KLDP/ Vim Tutor]가 그나마 자세한데, 이왕이면 vi 를 몰랐던 사람들도 이 바꾸기 기능에 감동하여 Vi 를 쓰게 되었으면 하는 바램으로 이런 저런 예를 추가하려 한다. |
당연히.. 이 글을 쓰는 본인도 vi 의 기능을 1% 라도 쓰고 있는지 의문이고, 이 글을 쓰고는 있지만, 바꾸기 기능 하나도 제대로 마스터하지 못했다. 따라서 예문이 지저분하거나 비효율적일 수 있는데, 더 깔끔하고 간편한 답을 아는 분은 언제라도 코멘트를 달아 주기를. |
(이하 vi, ViEditor 는 실제로는 Vim, 즉 VI improved 버전을 의미한다) |
== # VIEditor == |
== # VI == |
Vi 의 기본 사용법은 알아서 공부하자. :-) MS 윈도우에서 사용할 경우, ESC 를 누를 때 한/영 전환이 자동으로 영문모드로 바뀌지 않기 때문에 불편하다. [http://kldp.org/script/pub/list.php3?table=zzem4 여기]를 뒤져보면 이 문제를 해결한 패치 버전이 있다. |
참고: |
-51,6 +50,34 |
}}} |
그런데 아무래도 저것만 가지고는 좀 불편하다. 그래서 "확장 정규 표현식"이 등장했다. |
{{{ |
+ : 1번 이상의 임의 번 반복. a+ 는 a, aa, aaa, ... 즉 aa* 와 동일. |
| : a|b 는 a 또는 b |
() : group, (ab|cd)ef 는 abef 또는 cdef |
? : 없거나 하나 있거나. ab? 는 a 또는 ab |
}}} |
위의 확장 정규 표현식은 [[Perl]]에서는 그냥 쓰면 되고, ViEditor 에서는 앞에 백슬래쉬를 붙여 a\+ 와 같이 사용한다. |
임의 번 반복 대신이 구체적으로 숫자를 줄 수도 있다. |
{{{ |
{n,m} : n번 이상 m번 이하 반복 (가능한 많이) |
{n} : n번 반복 |
{n,} : n번 이상 반복 (가능한 많이) |
{,m} : m번 이하 반복 (가능한 많이) |
{} : 0 번 이상. * 와 동일 |
{-n,m} : n번 이상 m번 이하 (가능한 적게) |
{-n} : n번 |
{-n,} : n번 이상 (가능한 적게) |
{-,m} : m번 이하 (가능한 적게) |
{-} : 0번 이상 (가능한 적게) |
}}} |
역시 vi 에서는 앞에 백슬래쉬를 붙여서 a\{2,5} 등과 같이 사용한다. |
위에서 "가능한 많이"와 "가능한 적게"는 뭔가? abcdebcdebcde 라는 예로 들면, a.*d 는 '''a'''bc'''d'''ebc'''d'''ebc'''d''' 에 매칭되고, a\{-}d 는 '''a'''bc'''d''' 에 매칭된다. |
참고: |
* http://kldp.org/HOWTO/html/Adv-Bash-Scr-HOWTO/x10468.html |
-58,8 +85,51 |
* http://kldp.org/Translations/html/Sed-KLDP/sedprograms.html |
== # 복수의 문자열을 하나의 문자열로 바꾸기 == |
이것은 결국 위의 정규표현식을 사용한 패턴을 특정한 문자열로 바꾸는 것이다. 웬만한 vi 기초 문서에서 간단하게라도 다루는 내용이다. |
{{{ |
:%s/[vV]i//g - vi 또는 Vi 를 null string 으로 치환한다. 즉 삭제한다. |
:%s/<.*>//g - html 화일에서 태그를 제거하는 경우인데, 이렇게 쓰면 <b><i>내용</i></b> 라는 줄이 있을 때 죄다 지워질 것이다. |
따라서 <.*> 대신에 <.\{-}> 를 쓰는 게 낫다. |
::%s/\(gnu\|Gnu\)/GNU/g - gnu 또는 Gnu 를 GNU 로 치환 |
}}} |
간단한 것이니 이 정도로 통과. |
== # 복수의 문자열의 복수의 문자열로 바꾸기 == |
사실 이 얘기를 하고 싶었던 것인데... 이것만 덜렁 쓰기가 뭣해서 서론이 장황해졌다. |
핵심은, 괄호를 사용하여 찾는 문자열 쪽에 그룹을 지정한 후에, 바꿀 문자열 쪽에서 그 그룹을 부를 수 있다는 것이다. |
{{{ |
\0 은 찾은 문자열 전체 |
\1 은 첫번째 괄호 |
\2 는 두번째 괄호 |
\3 은 세번째 괄호 |
... |
}}} |
괄호의 순서는 여는 괄호 "(" 의 순서로 따진다. 또 . 나 [list] 등이 괄호안에 있을 경우는 실제로 검색된 문자열을 의미한다는 것에 유의. 즉 abef 라는 스트링이 있고 \(ab\|cd\)ef 로 검색했다면 \1 은 ab 가 된다. |
다음과 같은 경우를 생각해 보자. html 화일 안에 수십개의 링크가 다음과 같이 나열되어 있다. |
{{{html |
<li><a href="http://www.aaa.com">aaa</a> |
<li><a href="http://www.bbb.com">bbb</a> |
<li><a href="http://www.ccc.com">ccc</a> |
... |
}}} |
이것을 내가 [[위키위키]] 페이지에 옮기려 한다. (사실 위처럼 깔끔하게 되어 있으면 그냥 html 코드를 써도 되겠지만) |
{{{ |
* [http://www.aaa.com aaa] |
* [http://www.bbb.com bbb] |
* [http://www.ccc.com ccc] |
... |
}}} |
다음의 한 줄로 만사형통. |
{{{ |
:%s/<li><a href="\(.\{-}\)">\(.\{-}\)<\/a>/* [\1 \2]/g |
}}} |
---- |
관련 링크: |