안녕하세요 마무입니다! 오늘은 전에 쓴 vi 기초가 아닌, 알고 있음 매우 좋은 "실용적인 vi 팁", ".swp파일이란", "vi 치환", "리눅스 정규표현식"에 대해서 포스트 하려고 합니다.
당연히 기초적인 vi 사용법은 다들 아실거라 간주하고 포스트 할 것이며, 만약 모르신다면
vi, vim, gedit : https://mamu2830.blogspot.com/2019/09/vi-vim-gedit.html
여기서 보고오시면 됩니다!
-----목차-----
1. vi 옵션 -r과 .swp 파일
i) vi 복구와 숨겨진 swp파일
ii) vi -r 자체의 부가적인 용도
2. vi 명령모드 유용한 키
3. vi ex 명령모드 유용한 명령어
i) vi 치환
ii) 숫자 대신 사용가능한 특수문자
iii) 리눅스 정규표현식
4. vi 환경변수
--------------
입니다.
1. vi 옵션 -r과 .swp파일이란
전에 vi의 기초 포스트를 다뤘을 때, 제가 옵션은 굳이 알 필요가 없다하면서 알려주지 않았는데요, 사실 알면 좋은 옵션이 하나 있습니다.
바로 '-r(recovery)' 옵션인데요
실제로 저희가 vi(vim)을 이용해 ':w(저장)'을 안한 상태에서 열심히 작업하고 있는데, 갑자기 시스템이 꺼지거나, 원거리 접속(ssh)를 이용중에서 인터넷이 불안전하여 끊기는 경우 어떻게 될까요?
네 당연히 작업중이던 vi내용은 저장을 안했으니, 저장이 안됩니다.
그런 경우 매우 낙심할 수 있는데요... Vi에선 그런 경우 복구할 수 있게 만들어놓은 시스템이 있습니다!
바로 원래 vim로 작업중이던 [파일이름] 끝에 ".swp(swap)"란 확장자가 붙은
"[.파일이름.swp]"이란 숨겨진 백업용 파일이 생기는 것이죠.
이것은 swap의 뜻 "대체하다"라는 뜻대로, 기존에 작업중이였던 내용들을 이 .swp파일을 이용해서 대체할(불러올) 수 있다는 것이죠!
그리고 그 때 복구하려 쓰는 옵션이 바로 이 '-r' 옵션이죠!
i) vi 복구와 숨겨진 .swp파일이란
일단 백문이 불여일견 한번 사진을 봅시다.
이렇게 "vi(vim) test"으로 "test"란 파일을 만들고, 위 사진처럼 글을 좀 써놓고 ':w"로 저장해줍니다. 그리고
이렇게 복구가 됐는지 확인하기 위한 글을(There are critical problems) 추가로 작성한다음, 갑자기 인터넷이 끊겨서 프로세스가 강제 종료된거라고 가정하며, 오른쪽 상단의 "x"를 눌러서 터미널을 종료해줍니다.
이렇게 말이죠. 그러면 "현재 터미널에서 프로세스(vim)가 실행중인데, 터미널을 닫으면 그 프로세스가 강제종료(kill)될거다"라고 말합니다.
우린 그것을 원하는거니 "Close Terminal"를 눌러줍니다!
그리고 터미널을 다시 연다음
이렇게 "ls -a"로 숨겨진 파일까지 보시면, ".test.swp"이란 파일이 생긴 것을 볼 수 있습니다.
저게 위에서 말한 "vim 복구용 파일"입니다. 저 파일이 있으면 저희는 이제 옵션을 써서 복구할 수 있는겁니다.
복구하기 위해서 "vim -r test(복구할 파일)"란 명령어를 적어줍니다.
그러면
이렇게
".test.wap이란 swap파일을 이용해서, 오리지널 파일 ~/test 복구가 완료됐습니다"
라고 뜹니다.
그리고 Enter를 누르시면
이렇게 저장 안했던 글들(There are critical problems)이 복구가 된것을 확인할 수 있습니다!
여기서 중요한 것은 복구는 됐지만, 당연히 저장은 안된 상태라는 것!
반드시 복구 이후 ":wq"로 저장해줘야합니다.
물론 사실 이 '-r'옵션을 안 사용하고 더 간단히 복구하는 방법도 있습니다.
vim 작업을 하다가 강제 종료될 경우, 기존 'test'파일을 vim으로 열어보시면
이렇게 "ATTENTION"이라며 당시 강제종료된 vim파일의 시간대와 호스트 이름등 정보가 나오며 밑에 보시면
"o"를 누르면, Read-only로 글을 읽고,
"e"를 누르면, 그냥 무시하고 파일을 열고
"r"를 누르면, 복구하고
"d"를 누르면, .test.swp파일을 삭제하고
"q"를 누르면, 그냥 현재 파일종료
"a"를 누르면, 멈춤이지만 같이 실행된 다른 명령어나 행동들 모두 멈춤
이라고 보이는데, 네 여기서 "r"를 눌러주면 바로 복구가 됩니다.
복구한 뒤에 vi 파일을 ":w"로 저장해주고, 생성됐던 .swp파일(여기선 .test.swp)을 지워줍니다.
왜냐면 이 swp파일이 복구한 뒤에 알아서 사라지는게 아니라서, 이후 이게 있음 vi로 "test"파일을 열 때마다 자꾸 귀찮게 저 위 사진이 뜨거든요
그러니 복구한 뒤에는 swp파일을 지워줍니다!
헷갈리는 "vim q(quit)와 a(abort)"의 차이를 좀 더 이해하기 쉽게 설명하자면, 원래 "vim -p(pages)[숫자] [파일이름]"이렇게 치면, 적은 페이지 수만큼 한번에 여러 vim을 파일을 열거든요?
사진을 보여주자면
이렇게 '-p3'란 옵션을 붙여서 vim으로 파일을 열면
이렇게 처음에 정한 이름 'testForOptionP'외에도 이름이 정해지지 않은 파일 2개가 추가로 열립니다(-p3를 했기에)
그리고
이렇게 남은 이름 없는 파일 2개가 남는데, 말 그대로 이름이 없기 때문에, 저장하려고 해도 당연히
이렇게 이름이 없다며, 저장이 안됩니다. 이럴경우엔
이렇게 ":w [파일이름]" 형태로 파일 이름을 정하면서 저장하면
이렇게 이름이 정해지며, 저장이 됩니다.
나가서 확인하면, 처음 vim을 열 때 적은 'testForOtionP(중간 p 어디갔누..)'와 따로 :w로 저장해준 'testForOptionP2' 둘다 저장된 걸 볼 수 있습니다.
아 3페이지요? 그건 저장 안하고 그냥 껐기에, 기존 vi와 같이 아무것도 파일이 남지 않았습니다.
어쨌든 이렇게 한번에 여러개 만드는 'vim -p' 옵션을 사용해서, 복구모드에서 abort와 quit의 차이를 알 수 있습니다.
한번 봅시다
이렇게 -p3 옵션으로 기존에 '.swp'파일이 있던 'test'를 열어보면
늘 그랬듯, 이렇게 복구 창이 뜹니다. 여기서 "q(quit)"를 눌러보시면
기존 복구창이 보이던 vim만 종료되고, 나머지 2페이지는 그대로 나옵니다.
하지만!
여기서 'a(abort)'를 누르시면
그냥 말 그대로 전체가 다 종료됩니다.
이게 바로 q(quit)과 a(abort)의 차이였습니다.
ii) vi -r 용도
사실 파일 이름 없이 "vi -r"를 치시면, 현재 로그인한 유저의 복구용 swp파일이 있나 전체 시스템에서 찾아서 보여주는데요
이렇게 root는 당연히 모든 곳을 갈 수 있으니, "mamu"라는 유저로 로그인을 한 뒤에 "vi -r" 명령어를 쳐봤습니다만 위에 보시면
현재 /home/mamu/ 디렉토리 뿐만 아니라 /var/tmp, /tmp 처럼 다른 디렉토리 내부에서도 .swp파일이 있는지 확인을 해주는 걸 볼 수 있습니다.
이 말은 즉슨, 여기서 확인되는 디렉토리에 접근을 했다는 뜻이고, 이 유저가 사용할 수 있는 디렉토리라는 걸 의미하죠!
여기 사진에서의 리눅스는 당연히 공부용으로, 보안에 대해서 설정을 1도 안했지만, 실제에선 당연히 유저는 자기 디렉토리 상위로 이동을 보통 못하게 해놓습니다.
디렉토리 제한을 둔다는 것이죠, 거기서 이 "vi -r"를 이용해 접근 할 수 있는 디렉토리를 알아내는건... 뭐 다양하게 사용할 수 있겠죠 ㅎㅎ?
2. vi 명령모드 유용한 키
vi 명령모드에서 알아두면 정말 유용한 키들이 있습니다.
그러나 그걸 알려주기 전에 기본적인 명령모드의 형식에 대해서 먼저 알려주려고 합니다.
명령모드에서 키의 사용은 사실
[줄을 나타내는 숫자][명령모드 키] 형식입니다.
무슨 의미냐
현재 커서가 있는 한 줄을 지우라는 "dd"인 경우 사실 먼저 '5'를 누른 뒤에 "dd"를 누르면 현재 줄에서 5줄을 지운다는 것이죠.
또한 한 줄을 복사하는 "yy"인 경우에도 "5yy"이렇게 '5'를 먼저 누르고 "yy"를 누르면 현재 줄에서 5줄을 복사합니다.
이렇게 왼쪽 하단에 5줄이 복사됐다고 뜨면서 말이죠.
그럼 이런 명령모드 형식을 알아봤으니, 이제 사용할 좋은 키들에 대해서 알아봅시다.
"[숫자]yy(yank yank)" : 줄을 복사한다.
"u(undo)" : ctrl + z처럼, 전에 했던 행위를 복구합니다.
"[숫자]dd(delete delete)": 줄을 잘라낸다(삭제가 아니라 잘라내는거라 p{paste}와 사용가능)
"p(paste)": 복사한 것을 붙인다.
'$' : 현재줄 끝으로 커서 이동
"/[문자]" : 현재 커서에서 밑으로 입력한 문자들을 찾음
"?[문자]" : 현재 커서에서 위로 입력한 문자들을 찾음
"n(next)" : 문자를 찾을 때, 다음 문자로 이동함
3. vi ex 명령모드 유용한 키
vi의 명령모드에서 ":"를 눌러서 갈 수 있는 ex(extended, 확장된) 명령모드에서 사용할 수 있는 정말 정말 유용한 명령어들이 많습니다.
그래서 가장 기본적인 것 ":w, :q, :wq!"등은 제외하고 쓰겠습니다.
여기서도 알아두셔야 할 것이 "ex명령모드"에서도 형식은
:[줄을 나타내는 숫자][명령어] 라는 겁니다.
무슨 소리냐, 문자를 치환하는 ":s/바꿀문자/바꾼 문자/"란 형식이 있는데, 이 경우에도
":5s/바꿀문자/바꾼 문자/" 이렇게 하면, 5번째 줄에서 문자를 바꿔라란 뜻이 된다는 것이죠.
자세한건 밑 i)에서 다루겠습니다.
그 외 ex명령모드에서 알아두면 좋은 명령어는
":[숫자]" : 적은 숫자의 줄로 이동
":nohl(no highlight)" : /[문자]나 ?[문자]를 사용할시, 찾은 문자들을 노란색으로 강조하는 하이라이트 현상을 보여주는데, 그것을 제거하는 것
i) vi 치환
정말 꼭 알아둬야 할 정도로 실용적인 기능으로, vi로 연 파일내에서 적혀있는 문자들을 원하는 문자들로 치환하는 명령어입니다.
기본 형식은
:[줄 숫자]s(소문자, substitute, 대체하다)/[기존 문자]/[바꿀 문자]/
입니다.
이렇게 명령어를 칠 경우, 줄에서 처음 나오는 기존 문자만 바꿉니다. 무슨 소리냐
Aprjun Apr apr
Aprjun Apr apr
이런 글이 있는데, 여기에 ":1,2s/Apr/jun/" 이렇게 치면
junjun Apr apr
junjun Apr apr
이렇게 된다는 것이죠.
그럼 한 줄에 있는 모든 문자를 바꾸려면 어떻게 해야하나? 그럴 때 위 형식에서 맨 끝에 "g(global)"를 붙여주면 됩니다!
:[줄 숫자]s(소문자, substitute, 대체하다)/[기존 문자]/[바꿀 문자]/g
이렇게 말이죠.
Aprjun Apr apr
Aprjun Apr apr
여기에서
":1,2s/Apr/jun/g" 이렇게 치면
junjun jun apr
junjun jun apr
이렇게 바뀐다는 것이죠.
여기서 사용하면 또 좋은 옵션이 하나 더 있습니다. 바로 맨 끝에 "i(ignore case, 대소문자 구분 무시하다)"를 추가하는 것이죠. 즉
:[줄 숫자]s(소문자, substitute, 대체하다)/[기존 문자]/[바꿀 문자]/gi
를 적어줄 경우
Aprjun Apr apr
Aprjun Apr apr
여기에서
junjun jun jun
junjun jun jun
이렇게 바뀐다는 것이죠.
ii) 숫자 대신 사용가능한 특수문자
아 그리고 VI에서 우리가 아는 숫자외에도, 여기서 숫자대신 사용할 수 있는 특수문자가 있습니다.
'$' : 끝
'%' : 처음부터 끝까지
'[시작하는 줄 숫자],[끝 줄 숫자]' : 예를 들어 '5,10' -> 5번째 줄에서 10번째 줄까지
이 기호들을 알고 있으면, 한 파일내 처음부터 끝까지에서 특정 파일 이름을 바꾸고 싶을 때
":%s/바꿀 문자/바뀐 문자/g(한줄에서 끝까지란 의미)" 이렇게 적으면 처음 줄부터 끝까지 싹다 바꾼다는 것이죠.
그리고 당연히 "%"는 "0,$"는 같은 의미이고요!
여기까지만 알아도 좋지만... 아쉽게도 현실은 더욱 까다롭죠
문득 이런 의문이 듭니다
'그럼 다른 단어와 붙어있는게 아닌 정확히 한 단어로 이루어진 문자들만 바꾸고 싶을 땐
어떡하지?'
라는 의문이 말이죠.
원래 컴퓨터 공학에선 어떠한 방대한 데이터중에서 정확히 원하는 데이터만 찾기 위해
사용하는 기술이 있습니다. 바로 "정규표현식(Regular expression)"라는 것이죠.
iii) 와일드카드와 정규표현식 차이와, 리눅스 정규표현식
원래 검색을 할 때 빨리 찾기 위해 사용하는 것중에서 "와일드카드(WildCard)"가 있었는데
그거랑 비슷한겁니다. 물론 와일드카드랑 정규표현식의 차이가 궁금할 수 있을텐데요
그 차이는
"와일드카드(wildcard)"는 사용하기에 훨씬 직관적이며 간단하다는 장점이 있고
"정규 표현식(Regular expression)"은 복잡한 대신 훨~씬 정확한 데이터를 추출할 수 있는 장점이 있다는 겁니다.
그래서 원하는 데이터를 찾는 활동을 할 때 자주 사용되며 그 예시로, 네트워크 보안에 사용하는 "침입탐지시스템(IDS, Intrusion Detection System)"에서 특정 공격에 사용되는 패턴을 찾고자 설정하는 "Payload Detction"옵션에
이 "정규표현식(Regular expression)"이 사용됩니다.
이 정규 표현식이 사실 꽤 많지만, 여기선 vi의 치환과 함께 사용할 때 꼭 알아두면 좋을 정규표현식만 알아보겠습니다.
'^[문자]' : 줄에서 맨 앞에 있는 문자만
'[문자]$' : 줄에서 맨 끝에 있는 문자만
'\<' : 단어의 시작을 나타냄, 꼭 이스케이프(\)와 같이 써야함
'\>' : 단어의 끝을 나나탬, 꼭 이스케이프(\)와 같이 써야함
위에서 배운 vi 치환과 함께 예시를 들어보겠습니다.
Aprjun Apr apr
Aprjun Apr apr
이 문자에서 ":%s/^Apr/jun/g"
이렇게 칠 경우, 한 줄에서 맨 앞에 있는 'Apr'만 'jun'으로 바꾸는 의미니
junjun Apr apr
junjun Apr apr
이렇게 될 것이고
Aprjun Apr apr
Aprjun Apr apr
이번엔 ":%s/Apr$/jun/g"
이렇게 치면, 한 줄에서 맨 뒤에 있는 'Apr'만 'jun'으로 바꾸라는 의미니
Aprjun jun apr
Aprjun jun apr
이렇게 바뀔겁니다.
또 정확히 Apr 단어만 바꾸고 싶으면
Aprjun Apr apr
Aprjun Apr apr
여기에서
":%s/\<Apr\>/jun/g" 이렇게 할 경우
Aprjun jun apr
Aprjun jun apr
이렇게 될 겁니다.
4. vi 환경변수
사실 진짜 vi를 잘 사용하기 위해 알아둬야 할 환경변수가 몇 개 있습니다.
예를 들어, 다른 코딩 에디터(visual studio, atom 등등)으로 프로그래밍을 하다가, vim으로 쉘 프로그래밍을 하려고 하면 항상 불편하게 느껴지는 것들이 많거든요? 그런 불편함을 줄여주기 위해 사용하는 변수들입니다!
아 환경변수가 뭔지 궁금하실 분들이 있으실텐데, 그건 설명하자니 좀 길어서... 여기에선
"환경(시스템 전체)에서 사용가능한 변수"라고만 알아두시고, 자세한건 다른 포스트에서 다루겠습니다!
제가 봤을 때 vi(vim)에서 사용하기 좋은 환경변수는
:set num(number) : 줄마다 번호를 매김
:set ai(autoindent) : auto(자동) indent(가장자리 여백)이란 뜻대로, 엔터를 눌렀을 때, 줄 첫번째가 아니라, 기존 커서 바로 밑으로 이동됨
:set sm(showmatch) : show(보여줘) match(매치되는 것을)이란 뜻대로, 프로그래밍 할 때 많이 쓰는 ()와 {}의 짝을 표시해주는 기능
:set ic(ignorecase) : ignore(무시해라) case(대소문자)라는 뜻대로, 문자열을 검색하는 기능을 쓸 때, 대소문자 구분을 안한다.
가 있습니다.
사실 새로운 걸 공부한다는 것은 정말 귀찮습니다. 또한 이 포스트에 적은 정보를 몰라도 vi는 사용 할 수 있기에 더욱 공부할 필요성을 못 느끼죠...
하지만 정말 장담하건데 위에서 말한 것들은 사용하시게 되시면, 평소 vi를 사용하는 것보다 최소 몇 배에서 최대 몇 십배는 더욱 작업 속도가 빨라지실 겁니다!
그러니 꼭 한번쯤은 보면서 배워보셨으면 좋겠습니다!
도움이 되셨다면 팔로우 클릭, 따뜻한 댓글을 달아주시면 저에게 정말 큰 힘이 돼, 포스트 퀄리티를 향상시키는데 큰 도움이 됩니다!
그럼 다음에 더 좋은 포스트로 찾아뵙겠습니다!
잘 확인하였습니다! Vim을 제대로 활용할 생각에 기대가 되는군요 ㅎㅎ
답글삭제꼭 도움이 됐음 좋겠습니다! ㅎㅎ
삭제정말 포스트하나하나가 주옥 같습니다. 감사합니다
삭제힘이 나는 댓글 감사합니다!!
삭제