[TCL] 소스(source) 파일에 행번호 달기

TCL/C-Shell/Scripts 2009.08.19 15:46
  • 안녕하세요? 나도 디지털 영화 판매자 <쿨잼> 입니다.
    이제 블로그에서도 위젯 및 링크 등을 통해 합법 다운로드 영화를 판매하실 수 있습니다.

    블로그 방문자 수도 올리고, 판매를 통한 수익창출도 해보시는건 어떠세요?

    현재 아이팟 터치 지급 이벤트도 진행중이랍니다.

    http://www.cooljam.co.kr

    cooljam 2009.08.19 16:06 신고
    • 광고성 댓글은 환영하지 않지만, 스팸 댓글은 아닌 것 같아 일단 그냥 둡니다.

      youngjr 2009.08.20 10:18 신고 DEL
크리에이티브 커먼즈 라이선스
Creative Commons License
스크립트 관련 글을 올리다 보니, 소스 설명을 위해 행번호를 달 필요가 생겼네요.
그래서, 소스(텍스트 파일)에 행번호를 달아주는 TCL 스크립트를 만들어 보았습니다.

1: #!/bin/sh
2: # \
3: exec tclsh "$0" "$@"
4:
5: if {$argc > 0} {
6:    set input_fn [lindex $argv 0]
7: } else {
8:    exit
9: }
10: set line 1
11: set input_fid [open $input_fn RDONLY]
12: set eof_flag [eof $input_fid]
13: while {!$eof_flag} {
14:    set buffer [gets $input_fid]
15:    set eof_flag [eof $input_fid]
16:    if {!$eof_flag} {
17:       puts "${line}: $buffer"
18:       incr line
19:    }
20: }
21: close $input_fid

1-3번째 줄은 TCL 스크립트를 실행하기 위한 번역기(interpretor)를 설정하는 부분입니다.
보통 sh 은 /bin에 있지만, tclsh은 임의의 디렉토리에 설치되기도 하기 때문에, tclsh의 경로를 절대 경로로 정해주는 것보다는, 이 방법이 유연한 것 같습니다.
5-9번째 줄에서 입력된 argument개수에 의해 필요한 값을 받아옵니다. 입력된 argument가 1개 이상이면, 첫번째 argument를 입력 파일 이름으로 해 줍니다.
TCL에서는 실행하는 파일 자체의 이름은 argv0 이라는 별도의 변수로 들어갑니다. (C 같은 언어에서는 argv[0] 이지요.) 나머지 argument들은 argv라는 list에 들어있기 때문에 lindex 명령을 이용하여, 0번, 1번, 2번 차례로 argument를 지정할 수 있습니다.

11번째 줄에서 파일을 텍스트 읽기전용으로 열어줍니다.
12번째 줄에서는 파일의 끝인지 검사하는 변수를 플래그로 설정했습니다.
13번째 줄의 while 루프에서 파일의 끝이 아니면 반복하도록 합니다.
14번째 줄에서 buffer라는 변수에 파일의 한 줄을 읽어옵니다.
16-19번째 줄에서 파일의 끝이 아니면, 행번호와 읽어온 내용을 출력하고, 행번호를 하나 증가시킵니다.
21번째 줄에서 열려진 파일을 닫아줍니다.

간단한 스크립트이지만, 기본적으로 텍스트 파일을 읽어서 어떤 처리를 하는 자주 사용되는 TCL 스크립트의 전형이라 할 수 있겠습니다.
파일 열기 전에 파일이 실제로 존재하는 지 확인한다든지 하는 부분이 빠져있네요. 이런 사소한 듯하지만, 사용자의 부주의로 인한 실수를 막아주는 것은 스크립트나 프로그램의 질을 높여주는 요소이지요.
다음 글에는 이러한 점을 보완하고, 여러가지 argument를 받는 보다 완성도 있는 구조를 소개드리겠습니다.

신고
posted by youngjr

[CSHELL] 백업(backup) 스크립트를 작성해 봅시다

TCL/C-Shell/Scripts 2009.07.29 23:45
크리에이티브 커먼즈 라이선스
Creative Commons License
C shell 스크립트 예제 첫번째입니다.
특정 디렉토리에 있는 파일들을 tar+gzip 으로 묶어서 백업을 수행하는 스크립트를 만들어 보도록 하겠습니다.
백업을 그냥하는 것은 심심하니까,

  1. 백업 파일을 만들 때 현재 날짜와 시간이 포함되도록 합니다.
  2. 하위 디렉토리들을 포함하도록 합니다.
  3. 하위 디렉토리 밑에 있는 임시 파일(~로 끝나는)들을 삭제한 후 백업을 수행하도록 합니다.

 1: #!/bin/csh -f
 2: set cur_dir = `pwd`
 3: cd /home/youngjr/Project1/source
 4: foreach i (SUB1 SUB2 SUB3)
 5:     echo "Cleaning $i directory..."
 6:     cd $i
 7:     rm -rf *~
 8:     echo "Done."
 9:     cd ..
10: end
11: set today = `date '+%y%m%d%H%M'`
12: set target_name = "prj1_src_${today}.tgz"
13: echo ""
14: echo "Starting backup process..."
15: tar cvzpf $target_name SUB1 SUB2 SUB3
16: cd $cur_dir
17: echo "$target_name is created."
18: echo "Backup complete."   

설명을 위해 소스에 행번호(숫자:)를 붙였습니다. 실제 실행을 위해서는 당연히 행번호를 제외한 소스를 입력하셔야 하겠죠.
아래는 전체 소스 설명입니다.
2번째 줄에서 현재 디렉토리를 cur_dir라는 변수에 저장해 둡니다.
set은 c-shell에서 변수를 저장하는 명령입니다. 변수명과 = 이후에 해당하는 값이 들어갑니다.
pwd는 현재 디렉토리를 보여주는 UNIX/LINUX의 기본명령입니다.
`pwd`처럼 명령어를 ` 로 묶어주면, 명령어의 결과가 변수값으로 지정됩니다.

4번째 줄의 foreach에서 10번째 줄의 end로 묶이는 부분은 반복되는 루프를 실행하는 foreach 문구입니다.
foreach 다음에 루프 구문 안에서 사용할 각각의 항목이 지정되는 변수를 적어주고(여기서는 i), 뒤에 ()로 묶여진 목록을 나열해줍니다. 여기서는 차례로 SUB1, SUB2, SUB3의 세 가지 값이 i라는 변수에 차례로 대입됩니다.
foreach-end 구문 안에서 $i 처럼 해당 변수 i의 값을 사용할 수 있습니다.
여기서는 각 하위 디렉토리인 $i 로 들어간 후 ~로 끝나는 임시 파일들을 모두 지우고 다시 상위 디렉토리로 나옵니다.

11번째 줄에서 기본 명령어인 date를 사용하여 현재 날짜와 시간을 문구로 만들어줍니다.
date를 그냥 실행하면, Wed Jul 29 23:34:24 KST 2009 뭐 이런 식으로 표시가 되는데, 파일 이름으로 사용하기 위해,
200907292334 와 같은 형식으로 표현해 줄 필요가 있습니다.
date '+%y%m%d%H%M' 과 같은 명령으로 해당 포맷을 얻을 수 있습니다. %S를 추가하면 초단위로 표시도 됩니다.
자세한 표현 방법은 date의 메뉴얼 (man date) 페이지를 참조하시기 바랍니다.
12번째 줄에서 현재 날짜, 시간을 포함한 최종 파일 이름을 만듭니다.
"" 로 묶여진 문자열 안에서 $today와 같이 set으로 지정된 변수를 사용할 수 있으며, 변수명을 ${today}로도 사용하기도 하는데, 변수명 다음에 _ 와 같은 문자가 오면, _ 도 변수명에 포함되어 버립니다. (예를 들면, 200907092334_src 로 표현하고 싶어서 $today_src 라고 쓰면, today가 아닌 today_src라는 변수를 찾는 문제) 이를 방지하려면, 변수명을 {}로 둘러싸서 구분하도록 합니다.

15번째 줄에서 tar를 이용하여 하위 디렉토리들을 압축합니다.
구버전의 tar는 zip 압축이 지원 안될 수도 있습니다.
참고로 tar로 zip 압축과 해제는

tar cvzpf TARGET.tgz targets (압축시)
tar xvzf TARGET.tgz (해제시)


로 할 수 있습니다.
마지막으로 저장했던 원래 디렉토리로 돌아온 후 마칩니다.

신고
posted by youngjr


티스토리 툴바