구글 검색을 통해 검색되는 관련 자료들을 모아모아 보았다. 앞으로 더 좋은게 발견되면 추가할 것이다.


JimyLinux








http://mwultong.blogspot.com/2006/09/vim-vi-gvim-find-and-replace.html


[문자열 찾기 바꾸기] Vim (Vi), Gvim 리눅스 텍스트 에디터 - 찾기/치환 Find and Replace


GVim 또는 Vim에서 문자열을 찾거나 치환(바꾸기)하는 방법입니다.


문자열 찾기(Find)


* 현재 문서를 편집중이라면, 키보드의 Esc 키를 눌러 편집모드에서 빠져나옵니다.


* 키보드의 슬래쉬(/)키를 누르고, 찾을 문자열을 입력합니다. 만약 foo 라는 문자열을 찾는다면

/foo

이렇게 하면 됩니다.


그런데 /키는, 위에서 아래로 찾는 것입니다.


아래에서 위쪽 방향으로 찾으려면 물음표(?)키를 사용합니다. 현재 커서 위치의 위쪽에 있는 foo 라는 문자열을 찾으려면

?foo

라고 하면 됩니다.



다음 문자열 계속 찾기


다음 문자열 찾기는 소문자 n 입니다. 만약 foo 가 여러 개 있다면, 아래쪽 foo들을 계속 찾게 하는 것입니다.


역방향으로 계속 찾으려면 대문자 N 을 누릅니다.



대소문자 구분 없이 찾기


Vim은 대소문자를 구분하여 찾기에 불편합니다. Vim 설정 파일인 .vimrc 또는 _vimrc 파일에,

set ignorecase

이런 줄을 삽입하면 대소문자 구분 없이 찾기를 할 수 있습니다. (▶▶ [.vimrc] Vim / Gvim 설정 파일 예제 - 리눅스 텍스트 에디터 참고)




문자열 바꾸기(치환)


* 현재 문서를 편집중이라면, 키보드의 Esc 키를 눌러 편집모드에서 빠져나옵니다.


* 콜론(:)을 누르고 %s/foo/bar 라고 하면 모든 foo라는 문자열이 bar로 한꺼번에 치환됩니다.


다음과 같이 c 라는 옵션을 붙이면

:%s/foo/bar/c

바꿀 때마다 바꾸어도 좋은지 물어보기에 더 안전합니다. y를 누르면 바꾸고, n을 누르면 다음으로 건너뛰고, a를 누르면 모두 바꿉니다.



:%s/<foo>/bar


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

fooZZZ

ZZZfoo

ZZZfooZZZ

이런 문자열 속의 foo 는 바꾸지 않습니다.




대소문자 구분없이 바꾸려면

:%s/foo/bar/i

이렇게 i 옵션을 붙입니다. 이것은 ".vimrc" 파일을 고치지 않아도 작동합니다.





전역 치환


이 경우

foofoofoofoofoofoofoofoo


이렇게

barfoofoofoofoofoofoofoo


문장의 첫번째 foo만 bar로 치환됩니다. 문장의 모든 foo를 bar로 치환하려면

:%s/foo/bar/g

이렇게 g 옵션을 사용합니다.



:%s/foo/bar/gi

이렇게 여러 옵션을 혼용할 수도 있습니다.





패턴을 이용한 찾기 바꾸기 응용

글쓴이 : 탐험가 (2001년 10월 06일 오후 04:09) 읽은수: 5,495 [ vi # 트랙백(0) 인쇄용 페이지 본문 E-Mail로 보내기 ]

vi 상황


자바에서 Vector를 이용하여 코딩하고 있었는데.. Vector는 불필요한 Synchronized를 위한 처리를 해서


오버헤드가 쩜 있을꺼 같아서.. 크기가 고정된 것은 String[](배열)로 바꾸려고 한다


vListData.get(1) --> vListData[1]로...1의 값은 숫자이고 여러 값으로 바뀔수 있음..


기존 해결책

검색해서....다 바꾼다..-_-aa


( 검색 한게 어딘가..-_-aa )


해결책

패턴 매칭으로..찾아본다..


:%s/vListData.get(([0123456789]*))/vListData[1]/g


끝~~


조금 설명하면.. 앞의 패턴에서 ( 과 ) 사이의 것을


대치할 패턴의 1에 넣는 것이 핵심이다.


두개 있으면 2하면 될까? 모르겠다...-_-aa


여튼..정확한 설명은 아니구요...대충 그렇지 않을까 싶은거니


확실하게 아는 분 있으면...답글 달아주세요..


혹..확인하며 바꾸고 싶으면..끝에 g대신 gc를 입력하면


검색한다음... 바꿀 부분을 알려준다...그때..y를 누르면


바꾸어준다...


혹 잘못된거 있으면 알려주시길..


Unix PowerTools란 책을 참고했습니다..


편안한 하루!


p.s SunOS에서 VI만 쓰는데 VI에서 Syntax Highlight쓸 수 없나요?


VIM을 깔면 보안상 문제는 안생기나요? -_-aaa


<  여러파일 확장자 바꾸기 | FTP계정만 주고 Shell계정은 주지 않기  >

패턴을 이용한 찾기 바꾸기 응용 | 답장: 2개(RSS) | 본문에 답장

정렬 : 

답장 무우 (2001년 12월 09일 오전 09:35)

[0123456789] 는 [0-9] 요로케...

2같은것도 다 먹는다는 거.. 실험해 보셔서 아셨져?


1 2 로 두개의 문자열 swap 을 할 수 있을 겁니다.

:%s/(앗싸)(좋구나)(108계단)/231/g

이렇게 하시면

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


이거 왕입니다. 엄청난 양의 데이터를 가진 문서에서

순서바꾸기를 할 때 정말끝내줍니다.


123 def ghi

432 ius dkf

089 cdo lks


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


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


제가 아는 한도에서는 이게 가장 깔끔 -_-/~


정규 표현식의 세계는 오묘한것 같아여 넘 흑 ㅠ.ㅠ/~

[ 이글에 답장 | 본문에 답장 | 책갈피 ]


답장 임동현 (2001년 10월 08일 오전 09:30)

vim 까세요..


vi 에서 느낄수 없는 수많은 기능이 존재합니다.


보안상 문제가 있을까요?.


거의 /tmp 이런 문제 빼곤 없을걸요?.


지금은 아마 다 패치 되지 않았나 쉽네요..


물론.. syntax on 도 되지요..




 문자열 바꾸기


:%s/ABC/DEF/g    global substitution

:%s/ABC/DEF/c    check 

 

# 내용수정


    * cw: 단어 바꾸기

    * r  : 한글자 바꾸기   R: 모두 바꾸기

    * ~ : 대소문자바꾸기



#: <범위>s/old/new/<옵션>


    * Ex)

          o:s/add/plus/g

                + 전체 문서에서 add 를 plus로 치환

          o:s//etc///etc/local//g

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


http://www.gentoo.org/doc/ko/vi-guide.xml


텍스트 치환


텍스트의 패턴을 치환하기 위해 우리는 ex 모드를 사용한다. 만약 여러분이 현재 줄에서 처음으로 나타나는 패턴을 치환하고 싶다면, :s/<regexp>/<replacement>/라고 입력하고 <ENTER>를 치라. 여기에서 <regexp>는 여러분이 찾고자 하는 패턴이고 <replacement>는 바꿀 문자열이다. 현재 줄에 있는 모든 패턴을 치환하고 싶다면 :s/<regexp>/<replacement>/g라고 입력하고 엔터를 치라. 파일 안에 있는 모든 패턴을 치환하고 싶다면, :%s/<regexp>/<replacement>/g라고 입력하라. (보통 여러분은 이것을 원할 것이다.) 만약 여러분이 파일 안에 있는 모든 패턴을 치환하고 싶지만, vi가 각각의 변경에 대해 여러분의 확인을 받도록 하고 싶다면 :%s/<regexp>/<replacement>/gc라고 입력하고 엔터를 치라. (g는"global"을, c는 "confirm"을 의미한다.)






http://mwultong.blogspot.com/2006/09/regex-numbers-only.html


[정규식] 숫자로만 이루어진 행 찾기/매치시키기 - 정규표현식 REGEX Numbers Only


문서 중에서, 숫자로만 이루어진 행만 찾는 정규식입니다. 0에서 9까지의 아라비아 숫자 외의 다른 글자가 섞여 있으면 찾지 않습니다.


울트라에디트/EmEditor 정규식


에디터의 "찾기" 대화상자에서, Use Regular Expressions 에 체크해 주어야 "정규식으로 찾기"가 작동합니다. (정규식이 아닌 일반 텍스트를 찾기 위해서는 이 옵션을 해제해야 합니다.)


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


^d+$



^ : 행의 첫부분

d : 0~9까지의 숫자

+ : 바로 앞의 글자 (여기서는 숫자)가 1개나 1개 이상 있음. (즉 숫자가 최소한 1개 있음)

$ : 행의 마지막 부분



Vim / Gvim 정규식


Vim(VI) 에디터에서는 다음과 같이 합니다.


/^d+$



/ : 이것은 정규식의 일부가 아니고 빔 에디터의 찾기 명령입니다.


또한, 이렇게 + 앞에 를 붙여야 합니다.



http://www.joinc.co.kr/modules.php?name=News&file=article&sid=49


2.3. ex 모드

2.3.1. 찾기/치환


vim 의 기능중 가장편리한 기능으리면 뭐니뭐니 해도, 정규표현식을 이용한 강력한 찾기기능과 치환기능이라고 할수 있을것이다. 물론 다른 대부분의 에디터들도 찾기기능과 치환기능을 제공하긴 하지만, vim 의 기능은 다른 에디터들에 비해서 정말로 독보적인 편리함과 강력함을 제공한다. vi 사용자가 다른 에디터로 넘어가기 힘든이유중 가장큰 이유가, 바로 "키를 이용한 방향입력" 과 "찾기 및 치환" 기능 때문이다.


사실 찾기 치환의 기능을 제대로 이해하고 사용하기 위해서는 정규표현식(regular expression) 에 대한 이해가 필요로 하는데, 이것은 다음의 사이트를 참조하기 바란다. 정규 표현식의 간략한 소개


먼저 찾기 기능에 대해서 알아보겠다.찾기기능은 ':/패턴/' 를 이용 하면된다.찾기 원하는 문자혹은 패턴을 입력하고 엔터키를 누르면 현재 커서위치에서 가장 가까운 곳에 위치한 문자열로 커서를 이동시킨다(문서 아래방향으로). 다음 문자열을 찾기를 원한다면 'n'키를 누르면 된다. 문서에서 가장 마지막에 이르르게 되면, 문서의 가장처음부터 다시 찾기 시작한다. 'Shift+n' 을 이력하면 반대 방향(문서의 위쪽으로)으로 찾기를 시작한다.


치환이야 말로 vim 의 꽃이라고 할수 있다.:[범위]s/[oldpattern]/[newpattern]/의 형식으로 사용하면 된다.범위 지정은 visual block 을 이용할수도 있으며, 직접 범위를 입력할수도 있다. visual block 를 이용한 치환은 visual block 를 지정한다음 ':' 를 입력해서 ex 모드로 넘어가면 된다. 그리고나서 ':'<,'>s/[oldpattern]/[newpattern/' 과 같은 방법으로 치환하면 된다.


visual block 를 사용하지 않고 직접범위를 입력할수도 있다.:[시작],[마지막]s/[old]/[new]/식으로 범위를 지정하면 된다. 여기에는 몇가지 지정된 범위를 위한 특수 기호들이 있다. '%' 는 전체문서(처음부터 끝까지), '.' 은 현재, '$' 은 마지막 을 나타낸다. 숫자를 입력할경우 숫자는 라인을 나타낸다. 다음은 간단한 사용예이다.


# 문서 처음부터 마지막까지의 char 를 _char_ 로 치환한다.

:%s/char/_&_/g


# 현재(커서위치)부터 마지막까지의 char 를 _char_ 로 치환한다.

:.,$s/char/_&_/g


# buf_.*[255], buf_in[255], buf_get[255] 와 같은 문자열을 hello 로 변경한다. 

:1,10s/buf_.*[255]/hello/g

               


마지막에 쓰인 'g' 는 global 이다. 즉 해당 라인 전체에 걸쳐서 검색후 치환한다. 'g' 를 사용하지 않을경우 라인에서 처음에 검색된 문자만 치환하고 다음 라인으로 넘어간다.



http://ling.snu.ac.kr/hpshin/class/LangAndCom0402/lecture/regExp.htm


정규표현식 기초


저자 전정호 (mahajjh@myscan.org)




Copyright (c) 2001 Jeon, Jeongho.

Permission is granted to copy, distribute and/or modify this document

under the terms of the GNU Free Documentation License, Version 1.1

or any later version published by the Free Software Foundation;

with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.




이 글은 유닉스 사용과 관리에 필수인 정규표현식을 설명합니다. 또, 정규표현식을 처리하는 C 라이브러리도 마지막에 설명합니다.

'linux' 카테고리의 다른 글

find 로 문자열, 파일 검색  (0) 2013.12.22
vim 단축키  (0) 2013.11.24
/usr/bin/ld: i386:x86-64 architecture of input file `./client.o' is incompatible with i386 output  (0) 2013.09.13
~~~.gch  (6) 2013.09.11
ls & grep  (0) 2013.09.11
Posted by bogus919
,

문자열찾기 방법 1 - 영어만 주로 가능 
# grep -rw "찾는문자열" ./ 

문자열찾기 방법 2 - 대/소문자 구분 안하고 검색 
# grep -i -l "찾는문자열" * -r 2> /dev/null 

문자열찾기 방법 3 - 한글, 영어 모두 가능 
# find . -exec grep -l "찾는문자열" {} \; 2>/dev/null 

문자열찾기 방법 4 - 한글,영어, 대소문자 안가리고 검색 
# find . -exec grep -i -l "찾을문자열" {} \; 2>/dev/null 

문자열찾은 후 치환 
# find . -exec perl -pi -e 's/찾을문자열/바꿀문자열/g' {} \; 2>/dev/null 

파일명 찾기 
# find / -name 파일명 -type f 

파일명 찾기(대소문자 구별없음) 
# find / -iname 파일명 -type f 

디렉토리 찾기 
# find / -name 파일명 -type d 

디렉토리 찾기(대소문자 구별없음) 
# find / -iname 파일명 -type d

특정 사용자 소유의 모든 파일을 찾을때는?
# find / -user "사용자 ID" -print

두세가지 문자열을 동시에 찾아야 할때는 egrep을 쓰면 아주 편합니다. 
예를 들어 
만약 그냥 grep으로 문자열1,2 를 찾으려면 
ps -ef | grep 문자열1; ps -ef | grep 문자열2 
와 같이 해야하는것을 egrep를 이용하면 

ps -ef | grep '문자열1|문자열2' 
와 같이 간단해집니다. 

# egrep '(pattern1|pattern2|pattern3)' file.txt

'linux' 카테고리의 다른 글

vi 에서 문자열 찾기 바꾸기 총정리  (0) 2014.11.02
vim 단축키  (0) 2013.11.24
/usr/bin/ld: i386:x86-64 architecture of input file `./client.o' is incompatible with i386 output  (0) 2013.09.13
~~~.gch  (6) 2013.09.11
ls & grep  (0) 2013.09.11
Posted by bogus919
,

vim 단축키

linux 2013. 11. 24. 03:09

h, j, k, l - 좌,하,상,우 커서이동

i - 현재 커서 위치에 Insert 하기
I - 현재 줄 맨앞에 Insert 하기
a - 현재 커서 다음칸에 Insert 하기
A - 현재 줄 맨뒤에 Insert 하기
o - 윗줄에 Insert 하기
O - 아랫줄에 Insert 하기

w - 단어 첫글자로 이동하기
W - 화이트스페이스 단위로 다음 글자로 이동하기
b - 백워드 방향으로 단어의 첫글자로 이동하기
B- 백워드 방향으로 화이트스페이스 단위로 다음 글자로 이동하기
e - 단어의 마지막 글자로 이동하기
ge - 백워드 방향으로 단어의 마지막 글자로 이동하기
gg - 문서 맨 앞으로 이동
G - 문서 맨끝으로 이동
^ - 문장 맨 앞으로 이동
0 - 라인 맨 앞으로 이동
$ - 문장 맨 뒤로 이동
f문자 - 문자의 위치로 이동 ; 를 누르면 계속 이동
F문자 - 백워드로 문자의 위치로 이동
t문자 - 문자의 앞위치로 이동 
T문자 - 백워드방향으로 문자의 앞위치로 이동

/단어 - 문서에서 단어 찾기 n이나 N으로 다음/이전 찾기
* - 현재 단어를 포워드 방향으로 찾기
# - 현재 단어를 백워드 방향으로 찾기

Ctrl + f - 다음 페이지 이동
Ctrl + b - 이전 페이지 이동
Ctrl + u - 페이지절반만큼 다음으로 이동
Ctrl + d - 페이지절반만큼 이전으로 이동
H - 현재 화면의 맨 위라인으로 이동
M - 현재 화면의 중간 라인으로 이동
L - 현재 화면의 마지막 라인으로 이동

]] - 포워드 방향으로 여는 컬리 블레이스( { )로 이동
[[ - 백워드 방향으로 여는 컬리 블레이스( { )로 이동
][ - 포워드 방향으로 닫는 컬리 블레이스( { )로 이동
[] - 백워드 방향으로 닫는 컬리 블레이스( { )로 이동
% - {}나 ()에서 현재 괄호의 짝으로 이동

dd - 현재 줄 잘라내기
dw - 단어 잘라내기
yy - 현재 줄 복사하기
p - 붙혀넣기
r - 현재 글자 교체하기
u - Undo
Ctrl + R : Redo
x - 현재 글자 지우기
X - 앞의 글자 지우기
> - 들여쓰기
< - 내어쓰기
. - 이전 명령어를 다시 실행

v - 비쥬얼모드(비쥬얼 모드에서 커서 이동해서 블럭지정 가능)
y - 복사하기
c - 잘라내기
cw - 단어 잘라내기
J - 다음 라인을 현재 줄의 끝으로 이어 붙힘
~ : 선택 문자 대소문자 변경
Ctrl + A : 숫자를 증가시키기
Ctrl + X : 숫자를 감소시키기

:w - 문서 저장하기
:q - 현재 문서 닫기
:q! - 저장하지 않고 닫기
:wq - 저장하고 닫기
:숫자 - 지정한 라인넘버로 이동

:new - 가로로 분할된 창 열기
:vs - 세로로 분할된 창 열기
Ctrl + w - 분할창 간에 이동하기
:tabnew - 새로운 탭 열기
:gt - 다음 탭으로 이동하기
:gT - 이전 탭으로 이동하기
:e ./ - 현재 탭에 오픈할 파일 탐색하기( ./ 는 현재위치에서 탐색 시작)
:colorscheme 스키마명 - VIM의 칼라스키마를 변경함(blue, desert, evening 등.. 스키마명에서 탭누르면 자동완성됨)

zc - 코드 접기(fold)
zo - 접힌 코드 펼치기
zd - fold 지우기
zR - 접힌 코드 모두 펼치기
zM - 코드 모두 접기
zD - 모든 fold 지우기

:buffers - 현재 Vim에서 여러 파일을 열었을때 버퍼에 있는 목록 확인
:buffer 숫자 - 버퍼 목록에 나온 숫자를 입력하면 해당 파일을 오픈함 ( :buffer 대신 :b 도 가능)
:bnext - 버퍼에 있는 다음 파일로 이동 ( :bn 도 가능)
:bprevious - 버퍼에 있는 이전 파일로 이동 ( :bp 도 가능)
:ball - 버퍼 목록에 있는 파일들이 가로로 분할된 창에 열림

Posted by bogus919
,

collect2: ld terminated with signal 11 [세그멘테이션 오류]

/usr/bin/ld: i386:x86-64 architecture of input file `./client.o' is incompatible with i386 output

/usr/bin/ld: i386:x86-64 architecture of input file `./*.o' is incompatible with i386 output

 

export CFLAGS='-m32'

export LDFLAGS='-m32'

가 안되면..

 

Object 파일. 즉, *.o 파일을 지워라..

'linux' 카테고리의 다른 글

find 로 문자열, 파일 검색  (0) 2013.12.22
vim 단축키  (0) 2013.11.24
~~~.gch  (6) 2013.09.11
ls & grep  (0) 2013.09.11
컴파일이야기  (0) 2013.09.08
Posted by bogus919
,

~~~.gch

linux 2013. 9. 11. 23:15

gcc로 컴파일 하다보면 .gch 파일이 생긴다

이게 뭐냐면 헤더파일을 미리 컴파일 해놓은건데

한번 컴파일 해놓은거를 저장해놓고, 이 파일이 있으면 헤더파일을 컴파일하지 않고 이걸 사용한다

precompiled header라고 한다

그래서 이게 있으면 헤더파일없이 소스파일만 있어도 컴파일이 된다


그래서 내가 헤더를 고쳐도 안고친걸로 확인했나보다 이 개새끼야 너땜에


'linux' 카테고리의 다른 글

vim 단축키  (0) 2013.11.24
/usr/bin/ld: i386:x86-64 architecture of input file `./client.o' is incompatible with i386 output  (0) 2013.09.13
ls & grep  (0) 2013.09.11
컴파일이야기  (0) 2013.09.08
makefile 사용하기  (0) 2013.09.08
Posted by bogus919
,

ls & grep

linux 2013. 9. 11. 00:29

현재 디렉토리에서 

list 라는 키워드를 포함하는 파일만 찾고 싶을때는

ls | grep list

라고 해주면 된다

'linux' 카테고리의 다른 글

/usr/bin/ld: i386:x86-64 architecture of input file `./client.o' is incompatible with i386 output  (0) 2013.09.13
~~~.gch  (6) 2013.09.11
컴파일이야기  (0) 2013.09.08
makefile 사용하기  (0) 2013.09.08
gcc 옵션  (0) 2013.09.08
Posted by bogus919
,

컴파일이야기

linux 2013. 9. 8. 02:55

컴파일 방법

  컴파일을 할 때, 소스 파일 이름만 넣어 주시면 a.out으로 실행파일이 만들어 집니다. 여기에 -o 옵션을 사용하면 만들어지는 실행파일의 이름을 지정할 수 있습니다.

]$ gcc test.c     -> 실행 파일의 이름은 a.out 
]$ gcc -o test test.c    -> 실행 파일의 이름은 test

  옵션의 위치는 바뀌어도 상관없습니다.

]$ gcc test.c -o test

  리눅스, 즉 유닉스를 사용하시다 보면 텍스트 화면에서 작업을 많이 하기 때문에 사용하는 프로그램과 커맨드에 따라서 매우 다양한 옵션을 보실 수 있습니다. 예로 현재 폴더 내에 모든 .h 파일에 대해서 define 문자열을 찾는 find 명령이 아래와 같습니다.

]$ find . -name *.h -exec grep -nr "define" {} ; -print

  복잡해 보이죠? GUI에만 쩔은 저에게는 답답하기까지 합니다. 그러나 익숙해 지면 GUI와는 다른 편리함이 있더군요. 여하튼 옵션에 대한 거부감이 있다고 하시면, 여하튼 편리함을 위해 만들어진 것이라는 것을 먼저 상기해 주세요.


  그러나 여기서 한가지 더 알고 넘어 가야할 것이 있습니다. 프로그램 하나를 만든다고 하더라도 소스파일 하나로 작성하기 보다는 기능과 특징에 따라 여러 개의 파일로 나누어 작성하는 프로그램 소스의 모듈화입니다.

 

소스를 모듈화

  소스를 모듈화하는 것에 대한 장점은 참 많습니다. 기능과 특징 별로 나누었기 때문에 소스를 추적하기에 편리한 점도 있지만 제 개인적인 경험과 생각으로는 아래와 같은 장점이 있습니다.

  1. 프로그램 작성을 더 체계적으로 작성할 수 있다

       C 언어든 파스칼이든 프로그램은 함수를 만들어 가는 작업입니다. C의 첫 실행 위치인 main()도 함수입니다. 프로그램을 작성해 나가다 보면 새로운 함수를 계속 만들게며, 유능한 프로그래머일 수록 만들어진 함수관리를 효율적이고 철저히 관리합니다. 

       함수를 부품이라고 한다면 이상이 있는 부품을 빨리 찾아 내서 고치던지 바꾸든지 처리해야 하겠습니다.


      저는 프로그램을 잘 짜는 사람을 유능한 프로그래머라고 생각하지 않습니다. 프로그램에 문제가 발생했을 경우에 빠른 시간 안에 그 원인을 찾아내고 방법을 마련해서 디버깅을 할 줄 아는 사람이야 말로 유능한 프로그래머라고 생각합니다.



       이렇게 처리하기 위해서는 부품인 함수를 프로그래머가 쉽게 손이 닿을 수 있도록 잘 정리해야 겠는데, 그 첫번째가 프로그램의 모듈화라고 말씀드리고 싶습니다. 내가 만든 프로그램이라고 하더라도 수만 라인이 넘는 소스파일이라면 위, 아래로 스크롤해 가면서 함수를 찾아 내야 한다면 그 자체가 고역일 것입니다. 

      만들어지는 함수는 공통된 부분이 있고, 그 공통된 부분 별로 따로 모아 둔다면 훨씬 관리가 쉽겠지요. 입력 부분, 출력 부분, 통신 부분, GUI 처리부분, .... 프로그램을 작성하다 보면 새로운 부분이 생기는데, 이를 파일별로 따로 작성하는 것이 매우 효율적이며, 부분부분 별로 함수를 모아 놓았기 때문에 프로그램 소스 코드를 더욱 체계적으로 관리할 수 있습니다. 

  2. 프로그램의 이해를 돕는다

       함수를 만드는 이유가 이 곳 저 곳에서 자주 사용하는 기능을 따로 만들어서 간편하게 사용하기 위함도 있습니다만 경우에 따라서는 한 곳에서 한번 호출하는데도 함수로 만드는 경우가 있습니다. 이는 길든 짧든, 내가 만든 프로그램이라도 소스를 읽기 편하고, 나중에 분석하기 편하게 하기 위해 복잡해 보이는 부분을 함수로 따로 때어 낸다는 것이죠.

      훌륭한 소스란 프로그램 하나하나의 행을 눈으로 읽혀질 때 거부감 없이 바로 이해되도록 작성된 것입니다.

     프로그램 루틴 중에 어느 한 부분이 기능에 매우 충실하게 잘 작성되어 있지만 다른 코드와 함께 섞여 있다 보니 전체적으로 난잡하게 보이는 경우가 있습니다. 이럴 때에는 그 충실하고 잘 만들어진 부분을 가감히 함수로 만들어 버립니다. 이제 여러 행, 여러 페이지로 된 그 부분을 간단하고 이해하기 쉬운 함수 이름 하나로 정리가 되었습니다. 

      거기에다가 그 함수를 적당한 이름의 파일로 분리했습니다. 이제 이 소스 파일에는 오로지 그 함수를 이용한 전체적인 코드만이 존재하고 전체적인 흐름이 한 눈에 들어 옵니다. 남들이 봐도, 또는 언성을 올리지 않고 설명을 해도 고개를 그떡이게 하는 이해하기 쉬운 프로그램이 좋은 프로그램입니다.

  3. 프로그램 간에 격리(Isolation)

      제가 특히 조심하는 부분 중에 하나가 바로 이부분입니다. 아무리 봐도 이상이 없는 코드인데, 실행만 하면 아주 엉뚱한 행동을 합니다. 따로 때어 내서 실행해 보면 이상이 없어요. 그런데, 프로그램 전체로 묶어서 실행하면 이게 또 영~ 엉뚱한 짓을 합니다.

      이렇게 되는 이유가 여러 가지이겠습니다만 분명히 다른 코드로부터 영향을 받기 때문입니다. 프로그램 코드는 자기와 관계된 코드하고만 서로 영향을 주고 받아야 겠습니다. 그래야 문제가 발생하면 추적할 수 있습니다. 그 수 만은 함수 중에 알지 못하는 어떤 놈으로부터 영향을 받아 어뚱한 짓을 한다면 정말 미칠 노릇이죠.

      실행 파일 하나에 모두 쓸려 들어갈 코드이지만 다른 소스코드와 분리되도록 작성된다면, 그리고 가급적이면 독립되도록 작성되어 진다면 프로그램이 더욱 안정된 코드가 될 것입니다. 그렇게 하기 위한 첫번째 작업이 모듈화입니다. 소스코드를 하나의 파일로 독립시켜 놓고 다른 소스코드에서 사용할 함수나 빌려갈 변수만 헤더파일(.h)로 공개하고 안에서는 지들 끼리만 놀게 한다는 것이죠. 


  4. 라이브러리화하기 편리합니다.

       새로운 시스템을 작성한다고 해도, 이전에 작성한 코드를 거의 60%에서 80%를 다시 사용한다고 해도 과언이 아닙니다. 물론 이전에 작성한 코드를 이 만큼 사용한다고 해서 개발 기간이 60%, 80%가 절감된다는 것은 아닙니다. 그만큼은 아니더라도 이미 원하는 기능을 실현하는 함수를 다시 사용하므로 시간을 벌 수 있을 것입니다. 그리고 무엇보다고 이미 이전에 사용했던 코드이므로 어느 정도 디버깅이되고 인증이된 코드이기 때문에 새로 작성한 것 보다는 에러가 날 위험이 적습니다. 

       물론 예전 코드에 알지 못했던 버그가 있을 경우 디버깅하는데 더 오랜 시간을 고생하게 하는 경우도 있습니다. 보통 이상 없이 사용했던 코드라면 과신하게 되거든요. 그러나 역시 이때 문제를 잡으면 다음 작업에서 그 고생한 만큼의 보답을 받게 됩니다. 

     이런 함수를 기능 별로 특징 별로 모아 놓았기 때문에 꺼내어 쓰기가 편하고 아예 라이브러리 파일로 다시 만들어서 사용하기가 편리해 집니다. 

 

모듈화한 프로그램 컴파일

  모듈화의 필요성에 따라 main.c, tcpip.c, rs232.c로 3개의 파일로 나누어서 프로그램을 작성했습니다. 이제 컴파일을 어떻게 할까요? 이렇게 합니다.

]$ gcc main.c tcpip.c rs232.c -o test

  간단하죠, 방법은. 그러나 문제가 있어요. 파일이 많아 질 경우 그 많은 파일 이름을 어떻게 일일이 타이핑해서 컴파일 하겠습니까? 또한 여기에 필요 라이브러리 파일이나 기타 옵션을 추가하면 더욱 복잡해 지겠지요. 물론 배치파일을 사용하면 되겠습니다.

  그래도 문제가 있습니다. 이미 컴파일이 끝나서 컴파일이 필요 없는 데도 다시 컴파일하게 됩니다. 물론 작은 프로그램이야 잠시 기다리면 되겠습니다만, 큰 프로그램일 경우 컴파일 하는데, 몇 분씩이나 걸린다면 안되겠지요. 그래서 나온 것이 Makefile입니다. 다름 시간에 Makefile 에 대해 자세히 말씀을 올리도록 하겠습니다.

'linux' 카테고리의 다른 글

~~~.gch  (6) 2013.09.11
ls & grep  (0) 2013.09.11
makefile 사용하기  (0) 2013.09.08
gcc 옵션  (0) 2013.09.08
tar 압축  (0) 2013.08.30
Posted by bogus919
,

makefile 사용하기

linux 2013. 9. 8. 02:48

간단한 Makefile 만들기

  설명을 위해 아래와 같이 6개의 소스 파일이 있다고 하겠습니다.

  • main.c와 main.h
  • tcp.c와 tcp.h
  • rs232.c와 rs232.h

  여기서 생각해야 될 점은 main.c를 언제 컴파일하느냐 하는 것입니다. main.c 는 rs232.c의 함수와 tcp.c의 함수를 사용하기 때문에 main.c 자체가 변경되는 것 외에도 rs232.h와 tcp.h가 변할 때에도 컴파일하는 것이 안전합니다.

  • main.c 자체가 수정되었을 경우
  • main.h 가 수정되었을 경우
  • rs232.h 또는 tcp.h 가 변했을 경우

  tcp.c와 rs232.c는 자기 자신이 바뀌거나 해당 헤더파일이 변경되면 다시 컴파일이 되도록 합니다. 이제 이를 위한 간단한 Makefile을 보시겠습니다.

간단한 Makefile 만들기 

  Makefile 의 구조는 아래와 같습니다.

목표: 아래 명령을 실행하게 되는 모든 조건에 해당되는 파일 목록
    실행 명령어

  이와 같은 구조로 필요한 만큼 나열하면 됩니다. 다음은 실제 Makefile 내용입니다.

 주의

명령어 앞에는 반드시 탭 문자로 간격을 띄워야 합니다. 
공백으로 띄우시면 make 실행 시 에러가 발생합니다.

sample : main.o tcp.o rs232.o
    gcc -lm -o sample main.o tcp.o rs232.o  <-- 명령어, 즉 gcc 앞에는 tab 키로 들여 쓰기를 해야합니다. 

main.o : main.c main.h rs232.h tcp.h 
    gcc -c main.c       <-- sample 에서 링크할 것이므로 여기에서는 -c를 사용하여 컴파일만 하겠습니다. 

tcp.o : tcp.c tcp.h 
    gcc -c tcp.c

rs232.o : rs232.c rs232.h 
   gcc -c rs232.c

sample : main.o tcp.o rs232.omain.o tcp.o, rs232.o 파일 중 변경되는 파일이 있다면
아래의 명령을 실행합니다.
     gcc -lm -o sample main.o tcp.o rs232.omain.o, tcp.o, rs232.o로 실행파일 sample 를 만듭니다.
main.o : main.c main.h rs232.h tcp.h

main.c, main.h, rs232.h tcp.h 파일 중 변경되는 파일이
있다면 아래의 명령을 실행합니다.

     gcc -c main.cmain.c 를 컴파일해서 main.o를 생성합니다.
tcp.o : tcp.c tcp.htcp.c, tcp.h 파일 중 변경되는 파일이 있다면
아래의 명령을 실행합니다.
     gcc -c tcp.ctcp.c 를 컴파일해서 tcp.o를 생성합니다.
rs232.o : rs232.c rs232.hrs232.c, rs232.h 파일 중 변경되는 파일이 있다면 
아래의 명령을 실행합니다.
     gcc -c rs232.crs232.c 를 컴파일해서 rs232.o를 생성합니다.

  대충 이해가 되시나요? 뭐야 이거? 하시는 분이 계실지 모르겠습니다. 위이 예제는 아주 무식하지만 직관적으로 바로 이해되는 아주 간단한 Makefile 예제가 되겠습니다.

 

이제부터는 make 로 컴파일 완료

  이제 쉘에서 make 라는 명령으로 간단히 컴파일하고 실행 파일을 만들 수 있습니다.

]$ make

   편하죠? 그런데 Makefile 을 이렇게 만들면 타이핑을 해야할 것이 너무 많지요. 대부분의 프로그래머는 아주 게으릅니다. 타이핑으로 먹고 사는 사람들이 타이핑 많은 거, 좋와하지 않죠.

  이제, Makefile 만의 매크로를 이용하여 타이핑하는 횟수를 줄여 보겠습니다.

 

$@ $* $< $?

$@목표 이름
$*목표 이름에서 확장자가 없는 이름
$<

조건 파일 중 첫번째 파일

$?목표 파일 보다 더 최근에 갱신된 파일 이름

   자, 소개한 매크로를 이용하여 Makefile의 내용을 좀더 간단하게 만들 수 있습니다. 링크하는 부분을 먼저 보겠습니다.

sample : main.o tcp.o rs232.o
    gcc -lm -o sample main.o tcp.o rs232.o

  여기서 $@는 무엇일까요? 네, sample이 되겠습니다. 그러므로 아래와 같이 수정할 수 있습니다.

sample : main.o tcp.o rs232.o
    gcc -lm -o $@ main.o tcp.o rs232.o

  이해 되시죠. 이 번에는 $*오 $<, $? 에 대해서 말씀드리겠습니다.

tcp.o : tcp.c tcp.h 
    gcc -c tcp.c

  $*는 목표 이름에서 확장자를 제거한 이름이니까 .o를 뺀 tcp가 되겠습니다. 그러므로 $*를 이용하면 이렇게 수정할 수 있습니다

tcp.o : tcp.c tcp.h
    gcc -c $*.c

  이해 되시죠? $<는 조건에 열거된 파일 목록 중 첫번재를 의미합니다. 그러므로 $<는 조건 파일인 tcp.c tcp.h 중에서 첫번째 파일의 이름에 해당되므로 tcp.c 가 되겠습니다. 그러므로 아래와 같이 바꿀 수도 있습니다. 저 같은 경우 제일 많이 사용합니다.

tcp.o : tcp.c tcp.h 
    gcc -c $<

  $? 는 "현재 목표 파일 파일 보다 더 최근에 갱신된 파일 이름"을 나타내는 매크로입니다. 뜻은 알겠는데, 도대체 어디에 사용하는지 필요성을 잘 모르겠네요. 여하튼 예로 따져 보변 tcp.o 후에 tcp.h 가 수정되었다면 tcp.h가 된다는 것입니다.

 

확장자 규칙 .c.o

  일반적으로 .o 는 .c 로 만들어 지므로 실은 위의 예를 아래와 같이 명령 실행 없이 작성해도 make가 실행이 됩니다.

sample : main.o tcp.o rs232.o
    gcc -lm -o $@ main.o tcp.o rs232.o

main.o : main.c main.h rs232.h tcp.h-> 명령 실행이 없다.
tcp.o : tcp.c tcp.h-> 명령 실행이 없다.
rs232.o : rs232.c rs232.h-> 명령 실행이 없다.

  에이~ 그런데 왜 처음부터 복작하게 썼어? 하시겠지만, 이는 $*, $<, $? 를 설명 드리기 위함도 있지만 위와 같이 처리하면 컴파일은 되지만 컴파일에 대한 상세한 옵션을 처리할 수가 없습니다. 위와 같이 Makefile을 작성하고 make 를 실행하면 아마도 아래와 같이 단순한 모습으로 컴파일 될 것입니다.

]$make
cc -c -o main.o mainc
cc -c -o tcp.o tcp.c
cc -c -o rs232.o rs232.c

  요렇게 말이죠. 그러나 컴파일 할 때에는 인클루드 경로명을 지정하는 것과 같은 옵션을 사용해야 합니다. 이렇게 자동으로 진행되는 것만을 의지할 수 없습니다. 그래서 아래와 같이 .o 를 어떻게 만들어 낼지를 make 에 알려 줍니다.

sample : main.o tcp.o rs232.o
    gcc -lm -o $@ main.o tcp.o rs232.o

.c.o:
    gcc -I/home/jwjw/prjs/include -g -c $<

main.o : main.c main.h rs232.h tcp.h
tcp.o : tcp.c tcp.h
rs232.o : rs232.c rs232.h

  이제 make를 실행하면 아래와 같이 컴파일되는 모습을 보실 수 있습니다.

gcc -I/home/jwjw/prjs/include -g -c main.c
gcc -I/home/jwjw/prjs/include -g -c tcp.c
gcc -I/home/jwjw/prjs/include -g -c rs232.c
gcc -lm -o sample main.o tcp.o rs232.o

  또한 소스 파일이 Makefile과 같은 폴더 안에 있다면 아예 아래와 같이 작성하셔도 컴파일이 됩니다.

sample : main.o tcp.o rs232.o
    gcc -lm -o $@ main.o tcp.o rs232.o
.c.o:
    gcc -I/home/jwjw/prjs/include -g -c $<

  그러나 문제는 각 소스에 대한 컴파일 조건이 매우 단순해 지게 됩니다. 즉, main.c 는 main.c 자신이 수정될 때만 컴파일이 됩니다. 위의 예에서 처럼 rs232.h가 수정되거나 아예 관계가 아주 깊은 main.h 가 수정되더라도 main.c 는 재 컴파일이 안됩니다. 소스끼리 관계가 있다며 하단 부분을 서술해 주셔야 합니다.

sample : main.o tcp.o rs232.o
    gcc -lm -o $@ main.o tcp.o rs232.o
.c.o:
    gcc -I/home/jwjw/prjs/include -g -c $<

main.o: main.c main.h rs232.h
rs232.o: rs232.c rs232.h
tcp.o: tcp.c tcp.h

  그래도 많이 줄어 들었죠? 그러나 이게 다가 아닙니다.

 

매크로로 치환

  예제의 main.o tcp.o rs232.o 의 파일 이름이 2번 중복되어 있습니다. 두번 타이핑을 해야 하는데, 앞서 말씀드렸듯이 프로그래머는 게으릅니다. 2번~? 귀찮습니다. 아래와 같이 수정해 봅시다.

OBJS = main.o tcp.o rs232.o

sample : $(OBJS)
    gcc -lm -o $@ $(OBJS)
.c.o:
    gcc -I/home/jwjw/prjs/include -g -c $<

 또는 $^ 를 이용하여 아래와 같이 수정할 수 도 있습니다. $^는 조건에 있는 모든 파일 이름을 대신하는 매크로입니다.

OBJS = main.o tcp.o rs232.o

sample : $(OBJS)
    gcc -lm -o $@ $^
.c.o:
    gcc -I/home/jwjw/prjs/include -g -c $<

 하는 김에 컴파일 옵션과 링크 옵션도 매크로로 치환해 보겠습니다.


OBJS = main.o tcp.o rs232.o
CC = -I/home/jwjw/prjs/include -g -c

sample : $(OBJS)
    gcc -lm -o $@ $^
.c.o:
    gcc $(CC) $<

 이렇게 매크로로 치환하여 Makefile 의 윗 행에 모아 두면, 내용 전체를 볼 필요 없이 매크로 부분만 보거나 수정해도 되기 때문에 편리합니다. 이래서 아래와 같이 수정하여 완성할 수 있습니다.

TARGET = sample
OBJS = main.o tcp.o rs232.o
CC = -I/home/jwjw/prjs/include -g -c

$(TARGET : $(OBJS)
    gcc -lm -o $@ $^
.c.o:
    gcc $(CC) $<

main.o: main.c main.h rs232.h
rs232.o: rs232.c rs232.h
tcp.o: tcp.c tcp.h

gccmakedep

  다른 것들은 모두 편리하고 좋은 것 같은데, Makefile 하단에 있는 파일 간의 종속에 대한 정보를 모두 타이핑해서 넣어야 할까요? 파일이 많을 경우 어떻게 일일이 입력할 수 있있겠습니까?  당연한 말씀입니다. 게으른 프로그래머에게는 말도 안되죠. 그래서 이와 같은 귀찮은 작업을 make에 떠 넘기겠습니다. 바로 파일간의 의존성을 찾아서 그 내용을 직접 구성해 달라고 요청하는 것이죠.

  이렇게 파일의 의존성을 검색해서 그 내용을 작성해 주는 것이 gccmakedep 입니다. 아래와 같이 수정해서 make dep를 실행합니다.

TARGET = sample
OBJS = main.o tcp.o rs232.o
SRCS = $(OBJS:.o=.c)
CC = -I/home/jwjw/prjs/include -g -c

$(TARGET): $(OBJS)
    gcc -lm -o $@ $^

.c.o:
    gcc $(CC) $<

dep : 
    gccmakedep $(SRCS)

  이렇게 추가 작성해서 make dep 를 실행하시면 make는 컴파일과 링크 작업 대신에 라벨 dep: 밑의 명령을 실행합니다. 새로 만들어진 SRCS는 OBJS에 열거된 파일 모록에 대해서 확장자를 .o를 .c로 바뀐 목록을 가지게 됩니다. gccmakedep는 소스 파일을 가지고 의존성을 검색할 수 있기 때문이죠.

]$ make dep
]$ vi Makefile

TARGET = sample 
OBJS = main.o tcp.o rs232.o 
SRCS = $(OBJS:.o=.c) 
CC = -I/home/jwjw/prjs/include -g -c 
    $(TARGET): $(OBJS) gcc -lm -o $@ $^ 
.c.o: 
    gcc $(CC) $< 
dep : gccmakedep $(SRCS)

# DO NOT DELETE
main.o: main.c /usr/include/stdio.h .........
tcp.o: tcp.c 
/usr/include/stdio.h .........
rs232.o: rs232.c /usr/include/stdio.h .........

  하단에# DO NOT DELETE 행과 함께 밑으로 각 .o 에 대한 관련 파일 목록이 자동으로 생성되는 것을 보실 수 있습니다. 이제 make를 실행하면 위 정보에 맞추어 컴파일하게 됩니다.

'linux' 카테고리의 다른 글

ls & grep  (0) 2013.09.11
컴파일이야기  (0) 2013.09.08
gcc 옵션  (0) 2013.09.08
tar 압축  (0) 2013.08.30
우분투 업데이트 서버설정  (0) 2013.08.30
Posted by bogus919
,

gcc 옵션

linux 2013. 9. 8. 02:26


-o 옵션 : gcc에서 만들 실행 파일명을 정하는 것. 안지정하면 a.out
%gcc -o filter filter_driver.c define_stack.c global_var.c


-c 옵션 : 컴파일하지만 링크하지는 않는 다는 것을 의미
%gcc -c filter_driver.c


-D 옵션 : 소스코드의 #define 문과 같다. 심볼에 대한 값을 지정
% gcc -c -DDOC_FILE=\"info\" -DUSE_POLL filter_driver.c
첫 번째 -D 옵션은 DOC_FILE 을 info 라는 문자열로 대치한다는 것
두 번째 -D 옵션은 USE_POLL 심볼을 정의한다.


-I 옵션 : 헤더파일이 위치한 디렉토리 지정
% gcc -c -I../headers filter_driver.c


-l 옵션 : 라이브러리를 지정. 파일명과 함께 붙여 쓴다.
% gcc -o plot main.o plot_line.o -lm
-lm 옵션은 수학 라이브러리를 포함한다는 것을 지정


-L 옵션 : 라이브러리 폴더를 찾아서 지정
% gcc -o plot -L/src/local/lib main.o plot_line.o -lm


-E 옵션 : 프로그램을 컴파일 하는 대신 전처리된 코드를 표준 출력으로 내보냄 <전처리>

-S 옵션 : 어셈블리 언어로 나온 결과를 저장 .c 대신 .s 가 붙는 파일을 만들어 낸다. <컴파일>

-c 옵션 : .o 로 끝나는 오브젝트 파일 생성 <어셈블>

 


[ C 언어 옵션 ]
-v 옵션 : (verbose) 컴파일러의 버전과 각 단계에서 실행하는 자세한 사항을 출력 (어떤 옵션으로 컴파일 하였는지)

-w 옵션 : 모든 경고 메시지가 나오지 않도록

-W 옵션 : 합법적이지만 다소 모호한 코딩에 대하여 부가적인 경고 메시지를 출력

-Wall 옵션 : 모호한 코딩에 대하여 훨씬 더 자세한 경고 메시지를 출력

 

 


[ 라이브러리 지정 옵션 ]

-static 옵션 : 공유 라이브러리가 아닌 정적 라이브러리와 링크

-shared 옵션 : 가능한 한 공유 라이브러리와 링크하고 공유 라이브러리가 없는 경우에는 정적 라이브러리와 링크

 

 


[ 디버깅, 프로파일링 옵션 ]

-p 옵션 : 프로그램을 prof 로 프로파일링 할 수 있도록 링크. mon.out 파일 생성됨. 프로그램 실행 통계 수치를 담고 있다.

 

'linux' 카테고리의 다른 글

컴파일이야기  (0) 2013.09.08
makefile 사용하기  (0) 2013.09.08
tar 압축  (0) 2013.08.30
우분투 업데이트 서버설정  (0) 2013.08.30
우분투 ip설정  (0) 2013.08.30
Posted by bogus919
,

tar 압축

linux 2013. 8. 30. 16:14

1. tar (압축이 아니라 그냥 하나의 파일로 만들어줌)


#압축 하기

tar -cvf [압축할이름] [압축할파일이나 디렉토리 이름]

#압축 풀기

tar -xvf [압축파일 이름]


2. tar.gz (이게 진짜 압축프로그램)

#압축하기

tar -zcvf [압축할이름] [압축파일이나 디렉토리 이름]

#압축풀기

tar -zxvf [압축파일 이름]




옵션을 좀만 보면 외우기가 참쉽다

'linux' 카테고리의 다른 글

makefile 사용하기  (0) 2013.09.08
gcc 옵션  (0) 2013.09.08
우분투 업데이트 서버설정  (0) 2013.08.30
우분투 ip설정  (0) 2013.08.30
우분투서버(UbuntuServer) /etc/resolv.conf 초기화 막기  (0) 2013.08.30
Posted by bogus919
,