vi 텍스트 찾기 바꾸기 관련 명령어 모음

멀뚱이의 이미지

vi 텍스트 찾기와 바꾸기 명령어를 인터넷에서 검색해 보았습니다. 하도 산재되어 있어서 한 군데로 모은 것입니다.

1. 문서 처음부터 마지막까지의 char 를 _char_ 로 치환한다.
:%s/char/_&_/g

2. 현재(커서위치)부터 마지막까지의 char 를 _char_ 로 치환한다.
:.,$s/char/_&_/g

3. buf_.*[255], buf_in[255], buf_get[255] 와 같은 문자열을 hello 로 변경한다.
:1,10s/buf_.*\[255\]/hello/g

4. 숫자로만 이루어진 행 찾기는 다음과 같습니다.

/^\d\+$

^ : 행의 첫부분
\d : 0~9까지의 숫자
+ : 바로 앞의 글자 (여기서는 숫자)가 1개나 1개 이상 있음. (즉 숫자가 최소한 1개 있음)
$ : 행의 마지막 부분

5. 전체 문서에서 add 를 plus로 치환

:s/add/plus/g

6. 현재 편집중인 전체 문서에서 /etc/ 를 /etc/local/ 로 치환

:s/\/etc\//\/etc\/local\//g

7. '앗싸좋구나108계단' 이 '좋구나108계단앗싸' 로 바뀝니다.

:%s/\(앗싸\)\(좋구나\)\(108계단\)/\2\3\1/g

8. 대소문자 구분없이 바꾸려면 i 옵션을 붙입니다. 이것은 ".vimrc" 파일을 고치지 않아도 작동합니다.

:%s/foo/bar/i

9. 정확하게 foo에 일치될 때만 바꿉니다. 즉 foo는 바꾸지만, foo 앞뒤로 다른 문자열이 붙어 있는 경우에는 바꾸지 않습니다.

:%s/\/bar

10. 정렬

123 def ghi
432 ius dkf
089 cdo lks

이걸 숫자를 가운데로, 두번째는 끝, 세번째 처음으로 보내려면

:%s/\([0-9]*\) \([a-z]*\) \([a-z]*\)/\3 \2 \1/g

11. 만약 3~5자리로 이루어진 모든 숫자를 검색하고 싶다면 다음과 같이 입력한다.

/[0123456789]\{3,5\} 또는
/[0-9]\{3,5\}

12. 만약 `ab'로 시작하는 소문자로 되어 있는 모든 단어를 삭제하려면 다음과 같이 입력한다.

:%s/ab[a-z]*//g

13. 만약 test라는 파일에 cpu가 들어있는 라인을 모조리 지우고자 한다면 vi mode에서 아래와 같이 사용한다.

:g/cpu/d

# g는 모든 라인에 적용한다라는 의미이고,
# d는 delete를 의미합니다.

14. stat0,stat1.....stat9 패턴이 있는 라인을 모조리 지우기

:g/stat[0-9]/d

15. 빈 줄 두 줄을 한 줄로 바꾸기

:%s/\n\n/\n/g

16. 두 칸을 한 칸으로 줄이기

:%s/ / /g

17. 탭을 스페이스 공백으로 바꾸기

:%s/\t/ /g

18. 마지막에 한 칸 띠우고 엔터된 것을 바로 엔터한 것으로 고치기

:%s/ $//g 또는
:%s/ \n/\n/g

19. 줄 첫 칸의 띠어쓰기를 없애기

:%s/^ //g

20. 잘못 바꾸기를 했을 때 되돌리려면 그냥 u 키를 누르면 됩니다.

dopesoul의 이미지

search 후엔 꼭 블록이 남더라구요. 이 블록을 해제하는 방법은 없습니까?
저같은 경우는 전혀 검색될 문자가 아닌 것들을 타이핑하여 블록을 해제하곤 하는데요
명령어로 존재하는지 궁금하네요.

g0rg0n의 이미지

저도 그냥 /wtfbbq 이런식으로 빨리찾기 해서 없애요;;;

18

ahsan의 이미지

:nohlsearch

쓰고 놓고 보니 밑에 있어서 지울려는데 지울수가 없네요

누굴까?의 이미지

:noh를 쓰면 블록이 없어집니다.

karkayan의 이미지

:set nohlsearch 를 하시면 검색할 때 블록이 안생기도록 합니다.

palsuet의 이미지

별로 아는 건 없지만 사족을 조금 달자면, 5번에

:s/add/plus/g

는 전체문서에 적용되는 게 아니고 현재 커서가 있는 줄에만 적용됩니다. 전체 문서에 적용하려면 다음과 같이 해야 합니다.
:%s/add/plus/g

또는
:g/add/s//plus/g

6번도 마찬가지로 커서가 있는 줄에만 적용되고, 덧붙여서 이 경우에는 다음과 같이 하는게 더 편합니다.
:s$/etc/$/etc/local/$g

$말고도 여러가지 문자를 쓸 수 있습니다. :나 & 등등. 그리고 u를 눌러 취소했는데(undo), 다시 하고 싶다면 (redo) Ctrl+R을 누르면 됩니다.
--
feel the gravity

feel the gravity

geunhong의 이미지

- 줄 뒤 공백문자들 모두 지우기
:%s/[ \n]*//g

- 빈 줄 모두 삭제하기
:g/^$/d

1day1의 이미지

치환(변환) 시에 이렇게는 안되는 것 같더라구요.(몰라서 일 수도 있음)

etc 를 var 로 바꾸는 경우

바꿀내용이 이런경우.

/etc/bind/zone
/var/lib/ /var/lib/etc
/etc/bind   /etc/apache

:%s/etc/var/g

이면 어떻게 될까요? (가장 많이 쓰이겠죠)

/var/bind/zone
/var/lib/ /var/lib/var
/var/bind   /var/apache

이렇게 되겠죠.

:%s/etc/var/

이 경우는 g 플래그 가 빠진경우는.

/var/bind/zone
/var/lib/ /var/lib/var
/var/bind   /etc/apache

마지막 줄의 두번째 etc 는 바뀌지 않겠죠.

:s/etc/var/

% 가 없으면, 커서가 있는 줄만 바뀌겠죠.

그런데,

/var/bind/zone
/var/lib/ /var/lib/etc
/etc/bind   /etc/apache

처럼 처음의 etc 만 바꾸고 싶을때는 어떻게 하느냐 이것이 안되는 것 같습니다.
물론 줄 번호를 안다면
:1s/etc/var/

이런식으로 s 앞에 줄번호를 모르는 경우에는 어떻게 할 방법이 없는 것 같습니다.

"/" 로 먼저 찾고

:s/etc/var/

로 해당 커서에서 변환하면 되겠지만, 한번에는 안되는 것 같습니다.

제가 모르고 있는 것인지도 모릅니다. ㅜㅜ

.
.
.

# 관련이 있는 자료
http://www.ranoma.com/board/viewbody.html?code=hard&page=6&number=14697&keyfield=&key=
http://byus.net/jsb/read.php?table=study&no=114&page=1

shell 스크립트 관련도 정리를 하면 좋겠습니다.

F/OSS 가 함께하길.. (F/OSS서포터즈 : [[FOSS/Supporters]], [[FOSS/Supporters/Group]]) - 블로그 활성화 프로젝트 : 하루에 하나씩 블로그 글 남기기 -

F/OSS 가 함께하길..

lifthrasiir의 이미지

:/etc/s/etc/var/라고 해 보세요.

멀뚱이의 이미지

소문자 a가 포함되지 않은 줄만 모두 삭제하려면 어떻게 하면 될까요?

===
JimyLinux

예진아씨의 이미지

grep 에서 -v 옵션을 사용하세요

임예진 팬클럽 ♡예진아씨♡ http://cafe.daum.net/imyejin

임예진 팬클럽 ♡예진아씨♡ http://cafe.daum.net/imyejin

ydhoney의 이미지

물론 간단한 쉘 명령어로 파일을 수정하는 방법도 좋겠습니다만, vi/vim 의 -c 커맨드를 이용하며 연속 vi 작업을 스크립트화 하여 사용하는것이 편리한 경우가 상당히 많습니다. 특히나 특정 파일에 대한 복잡다양한 작업들을 진행하는데는 실제로 쉘 파이프나 펄 정도를 이용하기에는 부담스러운 경우도 존재합니다. 사용자의 쉘/perl에 대한 숙련도 가 떨어지는 경우라면 더욱 심하겠지요.

이러한 경우 이런 다양한 종류의 vi의 커맨드를 알고 있다면 이를 이용한 커맨드 스크립트를 작성하여 vi작업 역시 자동화할 수 있는 여지가 있고, 몇가지 커맨드 연속 사용만을 가지고도 특정 파일에 대한 복잡다양한 에디팅을 자동화할 수 있기에 vi의 커맨드에 대한 끊임없는 질의는 vi사용자 뿐만이 아니라 시스템 관리자에게도 많은 도움을 주는 좋은 쓰레드가 될 수 있습니다. ^^
 
====================어흥====================
짖지마시고 말씀을 하세요.

익명사용자의 이미지

:%g!/a/d

g : 다음이 패턴이 나타나는 줄에 대해 명령을 실행
g! : 다음의 패턴이 나타나지 않는 줄에 대해 명령을 실행

...입니다.

Prentice의 이미지

:v/a/d

%는 보통 생략 가능하고 g! 대신에 v를 쓸 수 있습니다.

esrevinu의 이미지

:%s/\<foo\>/bar/g

--
foldl (flip (:)) [] "universe"

totohero의 이미지

위에 소개된 것들이 sed 명령이죠? emacs에도 sed 명령을 바로 입력할 수 있는 함수가 있다면 좋겠다는 생각이 드네요. (물론 shell-command를 사용해도 되겠지만 결과를 간단히 테스트해보고 전체 적용한다든지 하는게 좀 불편하더라고요.)

nonots의 이미지

저도 vi 에디터 하나로(?) 밥먹고 살다시피 하는데
몰랐던 귀한 정보를 알게됐군요..
고수님들 고맙습니다.
..
이나저나 언제쯤 vi 폐인에서 벗어나려는지..

=== 건달의 경지를 꿈꾸며 ===


=== 건달의 경지를 꿈꾸며 ===

멀뚱이의 이미지

본문에 오류가 있었습니다

15. 빈 줄 두 줄을 한 줄로 바꾸기

:%s/\n\n/\r/g

15-1. 빈 줄 한 줄을 두 줄로 바꾸기

:%s/\n/\r\r/g

===
Wikipedian
WonYong

익명 사용자의 이미지

그렇군요. 근데 궁금한게 있는데...

newline charater를 검색할때는 \n로 하면 검색이 되는데
삽입할때는 \r로 넣어야 하는 이유가 있을까요?

snowall의 이미지

이제 겨우 치환과 편집기능을 사용하는 제게는 너무 좋은 자료군요. 어디 적어놔야겠네요.^^
--------------------------
snowall의 블로그입니다.
http://snowall.tistory.com

피할 수 있을때 즐겨라! http://melotopia.net/b

ydhoney의 이미지

# g는 모든 라인에 적용한다라는 의미이고,
# d는 delete를 의미합니다.

에서

g는 모든 라인에 적용한다라는 의미이고 ==> g == grep, 즉 해당 문구가 들어간 라인만 grep 해서..

정도로 이야기를 해 주는것이 올바른 것이 아닐까 싶습니다.

사실 모든 라인에 적용한다 라는 의미라면 % 에 대해서 언급하면서 이야기하는게 맞지 않을까 싶습니다. 딴지를 걸려고 한 것은 아니고 이 쓰레드를 보다가 혼동을 일으키실 초보분들이 계실까봐 미리 말씀드립니다.
 
====================어흥====================
짖지마시고 말씀을 하세요.

멀뚱이의 이미지

제가 쓴 본문 중에서,

7. '앗싸좋구나108계단' 이 '좋구나108계단앗싸' 로 바뀝니다.
:%s/\(앗싸\)\(좋구나\)\(108계단\)/\2\3\1/g

이것을 응용하면, 일련번호를 모두 바꿀 수 있습니다.

질문.

'2008년 3월 1일' -> '2008-3-1'
'1999년 2월 5일' -> '1999-2-5'

이런식으로, 날짜들을 모두 일괄적으로 바꾸려면?

답변.

:%s/\(\d\)\(\d\)\(\d\)\(\d\)년 \(\d\)월 \(\d\)일/\1\2\3\4-\5-\6/g

질문.

'2008년 3월 1일' -> '2008-03-01'
'1999년 2월 5일' -> '1999-02-05'
'1949년 12월 25일' -> '1949-12-25'
'1999년 2월 11일' -> '1999-02-11'
'2011년 12월 3일' -> '2011-12-03'

이런식으로, 날짜들을 모두 일괄적으로 바꾸려면?

답변.

일단, 포맷을 통일시켜줍니다.
즉, 0000년 00월 00일 식으로 포맷을 통일시킵니다.

:%s/년 \(\d\)월/년 0\1월/g
:%s/월 \(\d\)일/월 0\1일/g

그러면 아래와 같이 됩니다.

'2008년 3월 1일' -> '2008년 03월 01일'
'1999년 2월 5일' -> '1999년 02월 05일'
'1949년 12월 25일' -> 동일
'1999년 2월 11일' -> '1999년 02월 11일'
'2011년 12월 3일' -> '2011년 12월 03일'

그런 다음에, 하나의 명령어로 전부 바꿉니다.

:%s/\(\d\)\(\d\)\(\d\)\(\d\)년 \(\d\)\(\d\)월 \(\d\)\(\d\)일/\1\2\3\4-\5\6-\7\8/g

planetarium의 이미지

\(\d\)\(\d\)\(\d\)\(\d\) 대신
\(\d\d\d\d\) 로 하나의 그룹으로 묶는게 나을 것 같습니다.

또한
\d\{1,2\} 와 같이 쓰면 숫자가 1~2개인 경우를 검색하기 때문에
포맷을 통일시키는 일이 필수는 아닙니다.
물론 0000-00-00 꼴에서는 두자리로 표현하는게 더 보기 이쁘긴 하지만...

esrevinu의 이미지

두번째 질문을 한 번에...

:%s/\(\d\{4\}\)\s*년\s*\(\d\{1,2\}\)\s*월\s*\(\d\{1,2\}\)\s*일/\=printf("%4d-%02
d-%02d",submatch(1),submatch(2), submatch(3))/g
paeksj98의 이미지

이번에 좀 숙지좀 해야 겠네요.

익명 사용자의 이미지

개발한 개발자는 저 많은 기능 다 기억할까???ㅋ

wk2006의 이미지

좋은 정보 감사합니다.

wind0204의 이미지

좋은 팁 감사합니다.
맨뒤의 g나 i같은것 외에도 다양한 옵션이 있습니다. ( :help s_flags <- 쳐보세요.)

akayong의 이미지

:$, s/char/_char_/gc
를 자주 사용합니당. 그러면 각 "char"에 매칭 되는 단어에서 바꿀지 말지 를 물어보는데
일괄적으로 하는거 보단, 필요한 경우 또는 char 가 다른 단어에 포함되는 단어인 경우 등등
요긴하게 쓰이더라구요

eun1505의 이미지

음..;;; 까먹지 않기 위해.. ㅡㅡ;;; 블로그에 주욱 드래그해서 긁어가요~
완전 반할뻔... ㅡㅡ;;;;

(방금 근 한시간 넘게... ;; 노가다한 1인... ㄷㄷ;;)