Homework 4… 11월 4일(금) 11:59pm 까지 Bash 셸 프로그램 개선 교재 p185 연습문제 watchfor: 한 사람 이상 조사할 수 있도록 개선 pick: 매개변수 없을 때도 동작하도록 개선 checkmail: 메일 받은 날짜와 시간 표시하도록 개선 교재 p185 연습문제 4.다음처럼 동작되는 calu.bash 유틸리티를 작성하라 calu는 정수에 대한 산술연산을 수행한다. –k 옵션은 calu에서 사용될 수 있는 연산자와 형식을 설명한다 5. 다음처럼 동작되는 sum.bash 유틸리티를 작성하라 sum은 정수에 대한 자동합계를 구하는 스크립트이다 n은 양의 정수이다 Unix/Linux
과제 제출 방법 Electrical Version1 Electrical Version2 fedora.incheon.ac.kr (117.16.244.59): /home/ul2011hwa 또는 ul2011hwb 또는 ul2011hwc에 자신의 학번으로 숙제방(디렉토리) 만들고 그 안에 복사 자신의 디렉토리 보호 권장: chmod 1700 directoryname Electrical Version2 multi.incheon.ac.kr (117.16.244.53): /export/home/ul2011hwa 또는 ul2011hwb 또는 ul2011hwc에 자신의 학번으로 숙제방(디렉토리) 만들고 그 안에 복사 컴퓨터 사이의 파일 복사는 ftp 를 이용하세요! vi 편집기 내용을 윈도우 파일로 복사하는 방법 telnet 화면상에서 복사할 내용 부분을 드래그 한 후 <enter>를 하면 복사가 되고 텍스트 편집기(메모장 등)에서 Ctrl+V를 하면 복사한 내용이 붙여 넣기가 됩니다 Unix/Linux
본 셸 프로그램 1 문제 1: 다음은 3초 마다 한번씩 stu가 로그인 했는지 조사하는 본 셸 프로그램 watchfor이다. 이 프로그램을 참조하여 매개변수로 입력된 사람이 로그인 했는지 조사하되 한 사람 이상도 매개변수로 입력하여 조사할 수 있도록 수정해보세요. (예, $ watchfor 'mysung|root|stu') [Hint: egrep] $ cat watchfor #!/bin/sh until who | grep stu do sleep 3 done echo stu is logged in Unix/Linux
정규 표현식 정규식의 예 [교재 p194, p413 참조] (주의1) 반드시 단일 따옴표 안에 ! (주의2) *, +, ? 은 이전 문자에 적용됨 grep, egrep 정규 표현식 : . [] * ^ $ \ (예) .nd ^.nd sw.*ng [A-D] \. a. a.$ im*ing egrep 확장 정규 표현식 : + ? | () (예) s.*w s.+w off|will im*ing im?ing 정규 표현식: grep 특수문자 . 임의의 단일 문자 [ ] 괄호안의 단일 문자 중 어느 것과 일치 * 문자 다음에 나타남, 바로 앞의 문자가 0번 h는 그 이상 발생 ^ 줄의 시작, [ ] 안에서는 제외(except) 의미 $ 줄의 끝 \(백슬래시) 메타 문자 앞에 위치, 메타 문자의 특수 의미 제거 확장 정규 표현식: egrep + 단일문자가 1번 이상 발생 ? 단일 문자가 0번 혹은 1번 발생 |(파이프 기호) “or” 연산자 역할 ( ) *, +, ? 메타문자가 괄호 안의 전체 표현식에 대해 동작 Unix/Linux
정규 표현식 (Regular Expression) 메타 문자 표:
정규 표현식 (Regular Expression) 예제:
정규 표현식 (Regular Expression) 확장 정규 표현식: egrep과 같은 유틸리티들은 확장된 메타 문자들을 지원한다
본 셸 프로그램 2 문제 2: 다음의 pick은 매개변수로 입력된 인수들을 취사선택하는 본 쉘 프로그램이다. 이 프로그램을 코딩하여 실행해 보고, 명령 줄에 아무것도 없으면 표준 입력으로부터 인수를 읽을 수 있도록 프로그램을 수정하라. 빈 칸을 적절히 다루고, q 도 잘 동작하도록 해보세요. $ cat pick #!/bin/bash for i do echo –n “$i? ” read response case $response in y*) echo $i ;; q*) break esac done Unix/Linux
본 셸 프로그램 3 문제 3 : 다음의 checkmail 본 쉘 프로그램은 명령 줄 매개변수로 입력된 값을 주기로 하여(단, 매개변수 입력이 없으면 3초로 지정) 반복적으로 전자우편함의 크기를 조사하여 메일이 왔는지를 알려주는 프로그램이다. 이 프로그램을 코딩하여 실행해 보고 마지막 메일이 온 날짜와 시간을 출력하도록 수정하세요. [Hint: /var/mail/`logname`의 마지막 수정시간] (Bonus: 메시지에 메일을 보낸 사람의 이름이 나타나도록 해보세요) [Hint:메일 파일의 From 행 참조 ) $ cat checkmail #! /bin/sh MAIL=/var/mail/`logname` t=${1-3} x=“`ls -l $MAIL`” while : do y=“`ls -l $MAIL`” echo $x $y x=“$y” sleep $t done | awk ‘$5 < $14 {print “You have mail”}’ Unix/Linux
(참고) junk.ksh Unix/Linux #! /bin/bash # junk script # Lorn shell version # author: Graham Glass # 9/25/91 # Initialize variables fileCount=0 # the number of files specified. listFlag=0 # set to 1 if the list option (-) is used. purgeFlag=0 # set to 1 if the purge (-p) option is used. fileFlag=0 # set to 1 if at least one file is specified. junk=~/.junk # the name of the junk directory. error () { # Display error message and quit cat << ENDOFTEXT echo Dear $USER, the usage of junk is as follows: echo junk -p means "purge all files" echo junk -l means "list junked files" echo junk <list of files> to junk them ENDOFTEXT exit 1 } # Parse command line for arg in $* do case $arg in "-p") purgeFlag=1 ;; "-l") listFlag=1 ;; "-*") echo $arg is an illegal option ;; *) fileFlag=1 fileList[$fileCount]=$arg # append to list let fileCount=fileCount+1 ;; esac done # Check for too many options let total=$listFlag+$purgeFlag+$fileFlag if (( total != 1 )) then error fi # If junk directory doesn't exist, create it if [[ ! (-d $junk) ]] 'mkdir' $junk # "mkdir $junk"is OK # Process options if (( listFlag == 1 )) 'ls' -lgF $junk exit 0 Fi if (( purgeFlag == 1 )) 'rm' $junk/* if ((fileFlag == 1 )) 'mv' ${fileList[*]} $junk # move files to junk directory. Unix/Linux
프로그램 가능한 텍스트 처리: awk awk : Aho, Weinberger, Kernighan awk -Fc [-f fileName] 'program' {variable=value}* {fileName}* -Fc 입력줄의 항목 구분자를 c로 정함 (default:tab이나 공백) -f fileName awk 프로그램을 화일로 만들었을 때 이를 지정함 'program' awk 명령어 안에 awk프로그램을 직접 기록한 경우 {variable=value}* 프로그램을 위한 변수 치환 {fileName}* 입력 줄을 표준 입력이 아닌 지정된 파일에서 받아들임 Unix/Linux
프로그램 가능한 텍스트 처리 awk 'program': 다음의 형식으로 된 하나 이상의 명령어 [ condition ] [ \{ action \} ] condition: BEGIN(첫번째 줄을 읽기 전), END (모든 줄을 읽고 난 후), 논리 연산자, 관계 연산자, 정규식을 포함하는 조건식 cf. 만일 condition이 생략되면 모든 줄에 대하여 수행됨 action(C-like): if ( 조건 ) 문장 [else 문장] while ( 조건 ) 문장 for ( 연산; 조건; 연산 ) 문장 break continue print printf "형식" next exit 변수 = 연산식 {문장들의 리스트 } action들은 C 언어처럼 semicolon(;)으로 구분함 (cf.) 만일 action이 생략되면 해당 줄은 표준 출력됨 Unix/Linux
프로그램 가능한 텍스트 처리 입력 줄의 항목 접근 BEGIN과 END $ awk '{ print NF, $0 }' float - $1 (첫 번째 항목) $2(두 번째 항목) …… - $0 (줄 전체) - 내장 변수 NF (현재의 입력 줄의 항목 개수) $NF (마지막 항목) - 내장 변수 NR (현재의 입력 줄의 줄 번호) - 내장 변수 FILENAME (입력 화일 이름) BEGIN과 END $ awk '{ print NF, $0 }' float $ cat awk2 BEGIN { print "start of file:", FILENAME } { print $1 $3 $NF } END { print "End of file" } $ awk -f awk2 float cf. print나 printf에서 컴마(,)가 없으면 연속 인쇄, 있으면 공백 인쇄 $ cat awk3 #2,3번째 줄에 대하여 항목 인쇄 NR > 1 && NR < 4 { print NR, $1, $3, $NF } $ awk -f awk3 float Unix/Linux
프로그램 가능한 텍스트 처리 연산자 사용자 정의 변수의 사용 - 초기값: null string 또는 정수 0 $ cat awk3 #2,3번째 줄에 대하여 항목 인쇄 NR > 1 && NR < 4 print NR, $1, $3, $NF $ awk -f awk3 float 사용자 정의 변수의 사용 - 초기값: null string 또는 정수 0 $ cat awk4 #줄을 표준출력에 보내고 줄과 단어 수를 셈 BEGIN { print "Scanning file" } { printf "line %d: %s \n", NR, $0; lineCount++; wordCount += NF; } END { printf "line %d, words = %d\n", lineCount, wordCount } $ awk -f awk4 float Unix/Linux
프로그램 가능한 텍스트 처리 제어구조(C-like) 줄 일치에 확장된 정규식 사용 [1-p709] $ cat awk5 [교재 p317] #각 줄의 항목을 역순으로 출력 { for ( i = NF; i >= 1; i--) printf "%s", $i; printf "\n"; } $ awk -f awk5 float 줄 일치에 확장된 정규식 사용 [1-p709] $ cat awk6 #t와 e 사이에 1개 이상의 단일문자가 나오는 줄 /t.*e/ { print $0 } 조건 범위: 콤마(,)로 분리되는 두 개의 조건 - 처음 조건을 만족하는 줄부터 두 번째 조건을 만족하는 줄까지의 범위 $ cat awk7 #strong 포함하는 줄부터 clear 포함하는 줄까지 /strong/ , /clear/ { print $0 } 내장함수 이용 가능 exp(), log(), sqrt(), int(): C-like substr(str, x, y): x번째 문자부터 y번째 문자까지의 str의 substring $ cat awk8 $ awk -f awk8 test Unix/Linux