본셸 (Bourne Shell) 기본셸로는 Bash 셜또는 C 셸을사용하라그러나스트립트를실행하기위해서는 Bourne 셸을사용하라 셸이름 man 페이지크기 상대적인복잡도 sh (Bourne) 44,550 1.00 csh (C) 76,816 1.73 bash (Bash) 127,361 2.86 zsh (Zsh) 133,565 3.00 ksh (Korn) 141,391 3.18 tcsh (Tcsh) 199,834 4.49
소개 모든유닉스시스템에서유효한것이며다양한프로그래밍언어를지원 Korn 셸의기초 Stephen Bourne에의해작성된최초의대중화된유닉스셸 Shell의공통적인기능이외에 Korn Shell에추가된기능들 변수를설정하고접근하는방법들 조건분기, 루핑과인터럽트조작을지원하는내장된프로그래밍언어 기존의리다이렉션과명령열운영의확장 새로운몇개의내장명령어 Bourne Shell 2
소개 Bourne 셸기능 내장명령어 프로그래밍언어 변수 리다이렉션 명령열 시작하기 trap set read <& >& for case while if {...} export readonly profile Bourne Shell 3
시작하기 /bin/sh sh 명령어 : 스크립트나터미널로부터수동적호출가능 대화형셸 : 시작시자신의홈디렉토리에서.profile 화일을찾음..profile 의존재유무에관계없이 prompt를내보내고사용자의명령을기다림 비대화형셸 : 어떤시작화일도읽지않음 Bourne Shell 4
변수 변수의생성및할당 ( = 전후에빈칸없게 ) {name=value}+ 변수가존재하면새로운값으로바꾸고, 존재하지않으면자동적으로만들어짐. 공백은 로. ( 예 ) $ name=meeyoung age=20 $ echo $name is $age meeyoung is 20 $ name=meeyoung Sung... error 문자열은따옴표 ( ) 로표시 $ name= MeeYoung Sung Bourne Shell 5
변수 변수로의접근 $name : name 의값으로대치 ${name} : name의값으로대치. 변수이름의일부로번역되는문자가숫자가표현식다음에올때유용 ( 예 ) $ verb=sing... 변수할당 $ echo I like $verbing... verbing 변수는없다 I like $ echo I like ${verb}ing... 성공 I like singing $ echo I like re${verb}ing... 성공 Bourne Shell 6
43 4.3 변수변수 변수로의접근 ${name-word} : 설정되었으면 name 의값으로대치, 그렇지않으면 word 의값으로대치 ${name+word} : name 이설정되었을때 word 만대치 ( 예 ) $ startdate=${startdate-`date`} $ echo $startdate... 설정된값보기 Tue Feb 4 06:51 CST 1998 $flag=1... 변수할당 $ echo ${flag+ flag is set }... 조건부메시지 #1 flag is set $ echo ${flag2+ flag2 2 is set }... 조건부메시지 #2 Bourne Shell 7
변수로의접근 43 4.3 변수변수 ${name=word} : name이설정되지않았으면 word를할당하고 name의값으로대치 ${name?word} : name 이설정되지않았으면 word 는표준에러채널로표시되고그셸은종료. ( 예 ) $ echo x=${x=10}... 디폴트값할당 x=10 $ value=${x? x x not set }... 접근성공 $ echo $value... 값보기 10 $ value=${grandtotal? grand total not set }... 미설정 grandtotal : grand total not set $ grandtotal=100 $ value=${grandtotal? grand total not set } 설정 Bourne Shell 8
변수 표준입력으로부터변수읽기 read {variable}+ ( 예 ) $ cat read.sh echo enter your name, age : \c read name age echo your name is $name echo your age is $age $ read.sh enter your name, age : meeyoung 20 your name is meeyoung your age is 20 Bourne Shell 9
변수 echo 모든명령어인자 (arg) 들을표준출력 ( 화면 ) 에표시해줌 C shell에서 $ echo n {string}* -n 출력에 newline 을생성 (default) 하지않도록해줌 Bourne shell 에서 $ echo {string}* 제어문자표시 : $ echo string 큰따옴표안에표기 \b backspace \c print line without new-line (Bourne shell에서사용 ) \f form-feed feed \n new-line \r carriage return \t tab \v vertical tab \\ backslash \0n where n is the 8-bit character whose ASCII code is the 1-, 2- or 3-digit octal number representing that character ( 예 ) $ echo Please enter your name: \c Bourne Shell 10
43 4.3 변수변수 변수의범위전환 export {variable}+ 환경변수로범위전환시키도록명시된변수들을표시 환경변수는대문자사용 ( 예 ) $ export... 어떤변수도명시되지않으면모든변수들의목록이나타남 export TERM $ DATABASE=/dbase/db... 지역변수생성 $ export DATABASE $ export... export에더해졌음 export TERM export DATABASE Bourne Shell 11
43 4.3 변수변수 변수의범위전환 $ env {variable = value}*[command] command 실행을위하여지정된환경변수에값을할당 ( 예 ) $ env. 환경을표시 PWD=/export/home/mysung TZ=ROK HZ=100 HOSTNAME=csblade MACHTYPE=sparc-sun-solaris2.9 sun solaris2.9 MAIL=/var/mail/mysung LANG=ko LOGNAME=mysung SHLVL=1 SHELL=/bin/bash HOSTTYPE=sparc OSTYPE=solaris2.9 HOME=/export/home/mysung TERM=ansi PATH=/usr/bin::/export/home/mysung/dir:/usr/local/bin:/usr/ccs/bin:/usr/sbin _=/usr/bin/env ( 실습 ) $ mkdir test ; mv myprog.c test ; cd test $ gcc myprog.c o myprog $ dir= ~mysung/test/ $ env PATH=$dir myprog Bourne Shell 12
43 4.3 변수변수 읽기전용변수 readonly {variable}+ ( 예 ) (cf) 환경변수로전환된변수의읽기전용상태는상속되지않음 $ password=nicechej... 지역변수의할당 $ echo $password nicechej $ readonly password... 보호 ( 수정방지 ) $ readonly readonly password... 모든 readonly 변수나열 $ password=chej... 변수수정시도 password : is read only... error Bourne Shell 13
변수 미리정의된지역변수 이름 $@ $# $? $! $_ 값모든위치매개변수의개별적으로인용된목록위치매개변수의수마지막명령의반환값마지막후면명령의프로세스 id 명령줄로부터혹은내장명령어 set( 나중에설명 ) 에의해할당된현재셸옵션 Bourne Shell 14
43 4.3 변수변수 ( 예 ) $ cat arg.sh echo there are $# command line arguments: $@ $ arg.sh nofile tmpfile there are 2 command line arguments: nofile tmpfile ( 예 ) $ sleep 1000 & 후면프로세스생성 29455 후면프로세스의프로세스 id $ kill $! 프로세스를사멸시킴 29455 Terminated $ echo $! 프로세스 id는아직도기억됨 29455 Bourne Shell 15
변수 미리정의된환경변수 이름값 $IFS 셸이명령어를실행하기전명령줄을토큰화시키는경우, 설정된문자를분리자로사용. 공백, tab, newline 문자를포함 $PS1 명령라인프롬프트형태를제어하며디폴트로 $ 를갖음. 명령줄프롬프트를변경하려면 $PS1을새로운형태로지정. $PS2 더많은입력이셸에의해요구될때명령줄의보조프롬프트형태를제어, 디폴트로 > 을갖음. 프롬프롬트를변경시새로운형태로지정해준다. 셸시작파일의실행 IFS: Input Field Separators Bourne 셸, Korn 셸 : $..profile PS1: Prompt String 1 C 셸 :%source.cshrc PS2: Prompt String 2 Bourne Shell 16
43 4.3 변수변수 ( 예 ) $ PS1= sh?... 새로운주프롬프트설정 sh? oldifs=$ifs IFS 의이전값을기억 sh? IFS= : 단어분리자를콜론으로변경 /* Bash에서는적용되지않음 */ sh? ls:*.c 실행성공! badguy.c open.c trunc.c writer.c sh? String= a long\ 긴문자열을할당 > string > 는보조프롬프트 sh? PS2=??? 보조프롬프트변경 sh? String= a long\ 긴문자열을할당??? string??? 는새로운보조프롬프트 Bourne Shell 17
산술계산 expr expression expression의요소들은반드시공백으로분리되어야한다. 연산자 의미 \* / % 곱셈, 나눗셈, 나머지 + - 덧셈, 뺄셈 = \> \>= \< \<=!= 비교연산자 \& 논리적 and \ 논리적 or : 문자열 matching 기타연산자 (substr, index, length) 지원하지않음 Bourne Shell 18
4.4 산술계산 산술계산 ( 산술및논리연산예 ) expression의요소들은반드시공백으로분리되어야한다. $ x=l... x의최초값 $ x=`expr $x + l`... x값증가 $ echo $x 2 $ x=`expr 2 + 3 \* 5`... * 계산후 + 계산 $ echo $x 17 $ echo `expr \( 2 + 3 \) \* 5`...\( \) 먼저계산 25 $ echo `expr \( 4 \> 5 \)`.4 > 5? 0 $ echo `expr \( 4 \> 5 \) \ \( 6 \< 7 \)`.4 > 5 또는 6 > 7? 1 ( 문자열 matching 연산예 ) $ echo `expr $LOGNAME :.* `. 일치하는문자열길이 ( 정규표현식만 ) 또는 $ echo `expr match $LOGNAME :.* `. 일치하는문자열길이 ( 정규표현식만 ) 6 (cf.) $ echo `expr LOGNAME :.* ` Bourne Shell 19
조건식 test expression 또는 [ expression ] 괄호는반드시공백으로둘러싸여야함 expression 이참이면 0 인종료코드를돌려주고그렇지않으면 0 이아닌 종료상태를반환한다. test 명령의옵션 [ 교재 p175 참조 ] Parentheses : \( \) 논리연산 :!, -a, -o 문자열 : -z, -n, =,!= 숫자 : -eq, -ne, -gt, -ge, -lt, -le 파일 : -r, -w, -x, -f, -d, -s Bourne Shell 20
제어구조 case-in-esac 패턴에대응하는것을찾아그패턴의명령들을실행하는다중 선택형식. expression은문자열로계산되는식이고, pattern은대표문자를포함할수있음 case expression in pattern { pattern }* ) list ;; esac Bourne Shell 21
제어구조 ( 예 ) $ more menu.sh #! /bin/sh echo menu test program stop=0 while test $stop -eq 0 do cat << ENDOFMENU 1 : print the date. 2,3 : print the current working directory. 4 : exit ENDOFMENU # ENDOFMENU 앞에빈칸없게 echo echo 'your choice? \c' read reply echo case $reply in "1") date ;; "2" "3") pwd ;; "4") stop=1 ;; *) # default. echo illegal choice # error. ;; esac done Bourne Shell 22
46 4.6 제어구조제어구조 for-do-done 단어리스트안의각맴버에대해명령의집합을한번씩실행 for name [ in { word } * ] do list done Bourne Shell 23
46 4.6 제어구조제어구조 ( 예 ) $ cat for.sh... 스크립트내용표시 for color in red yellow green blue do echo one color is $color done $ for.sh... 스크립트실행 one color is red one color is yellow one color is green one color is blue Bourne Shell 24
46 4.6 제어구조제어구조 if-then-fi fi if list1 then list2 elif list3... elif는여러번반복가능함 then list4 else list5... else는 1번이하발생함 fi Bourne Shell 25
46 4.6 제어구조제어구조 $ cat if.sh echo -n enter a number : read number if [ $number -lt 0 ] then echo negative..$number < 0 이면음수 elif [ $number -eq 0 ] then echo zero.. $number = 0 이면 0 else echo positive fi $ if.sh... 스크립트실행 enter a number : l positive $ if.sh... 스크립트다시실행 enter a number : -l negative Bourne Shell 26
제어구조 trap 번호가붙여진 signal을받을때마다셸에게 command 를실행하도록지시. 여러개의 signal이받아들여지면번호순으로 trap됨 ($ kill l 로 signal 확인 ) signal 번호 0 이지정되면, 셸이종료 (exit) 됐을때 command 가실행됨 [ 신호는참고서적 p565 참조 ] 단 SIGKILL(9) 과 SIGSTOP(23) 은 trap 할수없음 ( 예 ) trap [[ [ command d]{ signal l} + ] $ cat trap.sh trap echo Control-C; exit 1 2 while : do echo infinite loop sleep 2 done # 2(interrupt) 신호가수신되면 로둘러싸인명령어가실행됨 Bourne Shell 27
메타문자 (meta character): 제어용특수문자 stty -a/all 현재사용중인터미널의메타문자들을보여줌 - erase( 한문자지우기 ^H) - kill( 한줄지우기 ^U) - werase( 마지막단어지우기 ^w) - rprint( 현재줄재출력 ^R) - flush( 대기입력무시, 재출력 ^O) - lnext( 다음문자를특수문자로보지않음 ^V) - susp/dsusp( 프로세스일시정지 ^Z/^Y) - intr(core dump 없이작업전면중단 ^C) - quit(core dump 하고작업전면중단 ^\) - stop/start( 터미날출력을정지 / 재시작 ^S/^Q) - eof( 입력끝 ^D) ( 예 ) $ stty erase ^H (bash 셸에서는안됨 ) $ stty echo $ stty echo $ stty sane ( 원래대로설정, 제어문자할당은제외 ) Bourne Shell 28
46 4.6 제어구조제어구조 until-do-done list1 의명령어를실행하고참이나 0 이아닌값을반환할때까지 list2 의명령을실행함 until list1 do list2 done Bourne Shell 29
46 4.6 제어구조제어구조 ( 예 ) $ cat until.sh x=1 until [ $x -gt 3 ]...$x가 3보다크면참 do echo x = $x x=`expr $x + 1` done $ until.sh x = 1 x = 2 x = 3 Bourne Shell 30
46 4.6 제어구조제어구조 while-done list1 의의조건이만족되는동안 list2 의명령을반복실행함 while list1 do list2 done Bourne Shell 31
46 4.6 제어구조제어구조 ( 예 ) $ cat while.sh x=1 while [ $x -le 3 ]...$x가 3보다작으면참 do echo x = $x x=`expr $x + 1` done $ while.sh x = 1 x=2 x = 3 Bourne Shell 32
46 4.6 제어구조제어구조 예제 : TRACK track [-ncount] [-tpause] [tpause] userid 지정된사용자의로그인과로그아웃세션을감시한다. Pause로명시된매초마다시스템을검색하여현재시스템에들어와있는사용자의목록을만든다. count 번의검색이완료될때까지수행 디폴트로 pause 는 10 초, count 는 100 번의검색임 Bourne Shell 33
track pause=1 trap 'track.cleanup $$; exit $exitcode' 0 # exit loopcount=100 trap 'exitcode=1; exit' 23 # INT/QUIT error=0 echo n >.track.old.$$ for arg in $* count=0 do while [ $count -lt $loopcount ] case $arg in do -t*) who grep $user sort >.track.new.$$ # pause=`expr substr $arg 3 10` diff.track.new.$$.track.old.$$ sed -f ;; track.sed >.track.report.$$ -n*) if [ -s.track.report.$$ ] # loopcount=`expr substr $arg 3 10` then ;; echo track report for ${user}: *) cat.track.report.$$ user=$arg fi ;; mv.track.new.$$.track.old.$$ esac sleep $pause done count=`expr $count + 1` if [! "$user" ] done then error=1 fi if [ $error -eq 1 ] then cat << ENDOFERROR usage: track [-n*] [-t*] userid ENDOFERROR exit 1 fi Bourne Shell 34
track $ cat track.cleanup echo stop tracking rm -f.track.old.$1.track.new.$1.track.report.$1 report $ cat track.sed # 7장 p326 sed 참조 /^[0-9].*/d /^---/d s/^</login/ /l / s/^>/logout/ Bourne Shell 35
diff 교재 p303 참조 diff [ -i -Dflag ] filename1 filename2 -i 대소문자의구분을무시한다 (ignore) -Dflag C preprocessor를위한출력을생성 출력형태 1: 첨가 (addition) firststart a secondstart, secondstop > 두번째파일에서첫번째파일로첨가되어야할부분 출력형태 2: 삭제 (deletion) firststart, firststop d linecount < 첫번째파일에서제거되어야할줄들 firststart와 firststop은첫번째파일의줄번호를의미하고 secondstart와 secondstop 은두번째파일의줄번호를의미 출력형태 3: 변경 (change) firststart firststop c secondstart, secondstop < 첫번째파일에서치환되어야할줄 --- > 치환을위하여사용되어야할두번째파일의줄 Bourne Shell 36
48 4.8 그밖의내장명령어 48 4.8 그밖의내장명령어 read 명령어표준출력에서변수의라인을읽음 null 명령어어떤연산도수행하지않음 (null builtin : 으로표기하고항상참을돌려줌 ) set 명령어변수나명령라인매개변수를지정하거나모든변수를표시 set -ekntuvx { arg }* Bourne Shell 37
set set 옵션 ( 교재 p188 표참조 ) $ set -v (verbose mode) $ set +v (verbose mode 제거 ) $ set -x ( 실행된명령에 + 표시, 전달된매개변수내용출력, 디버깅에좋음 ) $ set (-v와 x를무력화시킴 ) $ set -- (double hyphens) 로매개변수시작알림 $ set -u ( 설정되지않은변수만나면에러발생 ) ( 예 ) $ set a b c $ echo $1 $ date 1999년 9월 29일수요일오후 02시 38분 03초 $ set -- `date` $ echo $6 02시 $ echo $@ 1999년 9월 29일수요일오후 02시 38분 03초 Bourne Shell 38
set -x 명령행옵션으로실행되는디버깅기능 $ cat set.sh set -vx a.c ls $1 set - echo $notset echo goodbye $LOGNAME set -u echo $notset $ set.sh b.c? 쉘명령앞에서변수배정정의하면그명령으로변수값이 export 됨 $ cat myname echo My name is $name and my argument is $1 $ name=mysung myname john set -k로매개변수를주어진명령의환경에위치시킴 $ set -k $ myname name=mysung john Bourne Shell 39
개선점 4.9 개선점 Redirection: >&, 2>&, <&, <&-, >&-( 표준출력닫은후명령실행 ) 순차적명령열 : (cd /; pwd) 과 { cd /; pwd; } 서브셸에서부모셸에서 반드시빈칸과 ; 으로구분 4.10 명령줄옵션 Bourne shell은다음명령줄옵션을지원한다. 옵션의미 -c string 명령 string을실행하기위해셀생성 -s -i 표준입력으로부터명령을읽고표준에러채널로메시지를보내는셀을생성 SIGTERM, SIGINT, SIGQUIT 시그널이모두무시되는것을제외하면 s옵션과같은대화형셀을생성 Bourne Shell 40
Control Characters ^c Value ^c Value ^c Value a, A <SOH> l, L <FF> w, W <ETB> b, B <STX> m, M <CR> x, X <CAN> c, C <ETX> n, N <SO> y, Y <EM> d, D <EOT> o, O <SI> z, Z <SUB> e, E <ENQ> p, P <DLE> [ <ESC> f, F <ACK> q, Q <DC1> \ <FS> g, G <BEL> r, R <DC2> ] <GS> h, H <BS> s, S <DC3> ^ <RS> i, I<HT> t, T <DC4> _ <US> j, J <LF> u, U <NAK>? <DEL> k, K <VT> v, V <SYN> 각키의의미는 ASCII Character Set ANSI X3.4 1968 참조 Bourne Shell 41
과제 1. 본셸프로그램 (watchfor, pick, checkmail) 개선 2. 교재 p193 연구과제 1: 전화번호부유틸리티작성 이름, 주소, 전화번호로검색이가능한전화번호부유틸리티를아래의두경우에대하여각각작성 전화번호데이터가프로그램과같은파일안에있는경우 ( 힌트 : here document) 전화번호데이터가프로그램과다른파일안에있는경우 3. junk 유틸리티작성 ( 참고서적 p192 연습문제 1) : 참고서적 p239~p241 p 참조 4. 완벽한 track 유틸리티 Borne shell version 작성 ( 스트링추출은 sed 나 awk 참조 : expr 에서 substr 동작하지않으므로 ) 과제제출방법 1. Electrical Version 1 csblade.incheon.ac.kr (211.119.245.149) 의 /export/home/2007hw/ulahw 또는 ulbhw에자신의학번으로숙제방 ( 디렉토리 ) 만들고그안에복사 자신의디렉토리보호권장 : chmod 700 directoryname 2. Electrical Version 2 csblade.incheon.ac.kr (211.119.245.75) 의 /home/2007hw/ulahw 또는 ulbhw에자신의학번으로숙제방 ( 디렉토리 ) 만들고그안에복사 자신의디렉토리보호권장 : chmod 700 directoryname Bourne Shell 42
본셸프로그램 1 문제 1: 다음은 3 초마다한번씩 stu 가로그인했는지조사하는본셸프로그램 watchfor이다. 이프로그램을참조하여매개변수로입력된사람이로그인했는지조사하되한사람이상도매개변수로입력하여조사할수있도록수정하라. ( 예, $ watchfor 'mysung root stu') $ cat watchfor #!/bin/sh until who grep stu do sleep 3 done Bourne Shell 43
본셸프로그램 2 문제 2: 다음의 pick ik 은매개변수로입력된인수들을취사선택하는본쉘프로그램이다. 이프로그램을코딩하여실행해보고, 명령줄에아무것도없으면표준입력으로부터인수를읽을수있도록프로그램을수정하라. 빈칸을적절히다루고, q 도잘동작하도록하라. $ cat pick ik #!/bin/sh for i do echo $i? \c read response case $response in y*) echo $i ;; q*) break esac done Bourne Shell 44
본셸프로그램 3 문제 3: 다음의 checkmail 본쉘프로그램은명령줄매개변수로입력된값을주기로하여 ( 단, 매개변수입력이없으면 6초로지정 ) 반복적으로전자우편함의크기를조사하여메일이왔는지를알려주는프로그램이다. 이프로그램을코딩하여실행해보고메시지에메일을보낸사람의이름이나타나도록하고우편함파일 (MAIL) 이존재하지않더라도잘동작하도록수정하라. $ cat checkmail #! /bin/sh MAIL=/var/mail/`logname` t=${1-6} 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 } Bourne Shell 45
#! /bin/ksh # 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 g # 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 l") listflag=1 ;; "-*") echo $arg is an illegal option ;; *) fileflag=1 filelist[$filecount]=$arg # append to list let filecount=filecount+1 ;; esac done junk.ksh k # 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) ]] then 'mkdir' $junk # "mkdir $junk"is OK fi # Process options if (( listflag == 1 )) then 'ls' -lgf $junk exit 0 Fi if (( purgeflag == 1 )) then 'rm' $junk/* exit 0 fi if ((fileflag == 1 )) then 'mv' ${filelist[*]} $junk # move files to junk directory. exit 0 fi exit 0 Bourne Shell 46
스트림편집 : sed 교재 p334 참조 스트림편집, 하나이상의파일을스캔하여특정조건에맞는모든줄을편집한다. 단순반복편집에유용하다. sed [ -e script ] [ -f scriptfile ] { filename }* -f scriptfile sed 편집명령을파일로저장수행 -e script sed 편집명령지정 (script = 'sed 폅집명령 ') sed 편집명령 addressrange s/expr/str / 정규식 expr이첫번째발생을문자열 str로대치 addressrange a/expr/str/g 모든정규식 exp을문자열 str로대치 address r name address줄뒤에화일 name의내용덧붙이기 address i\ text address줄뒤에텍스트 text 삽입 addressrange d addressrange로지정된줄을삭제 addressrange c\ text addressrange로명시된텍스트를 text로치환 addressrange a\ text addressrange 로명시된텍스트뒤에 text 를첨가 만일주소가명시되어있지않으면모든줄에대하여적용 Bourne Shell 47
sed ( 예 ) $ sed 's/^/ /' arms > arms.indent 파일의들여쓰기실행 ( 예 ) $ sed 's/^ *//' arms.indent 각줄앞에있는공백제거 ( 예 ) $ sed '/a/d' arms 정규식 'a' 를포함하는모든줄을삭제 ( 예 ) $ sed '/\<a\>/d' arms 단어 'a' 를포함하는모든줄을삭제 ( 예 ) $ sed -e 's/^/<< /' -e 's/$/ >>/' arms '<<' 를줄의맨앞에, '>>' 를줄의맨뒤에삽입함 Bourne Shell 48
프로그램가능한텍스트처리 : 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}* 입력줄을표준입력이아닌지정된파일에서받아들임 Bourne Shell 49
프로그램가능한텍스트처리 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 이생략되면해당줄은표준출력됨 Bourne Shell 50
입력줄의항목접근 프로그램가능한텍스트처리 - $1 ( 첫번째항목 ) $2( 두번째항목 ) - $0 ( 줄전체 ) - 내장변수 NF ( 현재의입력줄의항목개수 ) $NF ( 마지막항목 ) - 내장변수 NR ( 현재의입력줄의줄번호 ) - 내장변수 FILENAME ( 입력화일이름 ) BEGIN 과 END $ awk '{ print NF, $0 }' inputfile $ cat awk2 BEGIN { printf "start of file:", FILENAME } { print $1 $3 $NF } END { printf "End of file" } $ awk -f awk2 inputfile cf. print 나 printf 에서컴마 () (,) 가없으면연속인쇄, 있으면공백인쇄 $ cat awk3 #2,3 번째줄에대하여항목인쇄 NR > 1 && NR < 4 { printf NR, $1, $3, $NF } $ awk -f awk3 inputfile Bourne Shell 51
프로그램가능한텍스트처리 연산자 $ cat awk3 #2,3번째줄에대하여항목인쇄 NR > 1 && NR < 4 print NR, $1, $3, $NF $a awk -f awk3 inputfile 사용자정의변수의사용 - 초기값 : 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 inputfile Bourne Shell 52
프로그램가능한텍스트처리 제어구조 (C-like) $ cat awk5 [ 교재 p317]# 각줄의항목을역순으로출력 { for ( i = NF ; i >= 1; i--) printf "%s", $i; printf "\n";" } $ awk -f awk5 inputfile 줄일치에확장된정규식사용 [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 Bourne Shell 53