4. Bourne 셸
4.1 소개 모든 유닉스 시스템에서 유효한 것이며 다양한 프로그래밍 언어를 지원 Korn 셸의 기초 Stephen Bourne에 의해 작성된 최초의 대중화된 유닉스 셸 Shell의 공통적인 기능 이외에 Korn Shell에 추가된 기능들 변수를 설정하고 접근하는 방법들 조건 분기, 루핑과 인터럽트 조작을 지원하는 내장된 프로그래밍 언어 기존의 리다이렉션과 명령열 운영의 확장 새로운 몇 개의 내장 명령어 Unix 시스템
4.1 소개 Bourne 셸 기능 내장 명령어 프로그래밍 언어 변수 시작하기 리다이렉션 명령열 trap set read <& >& for case while if {...} export readonly profile Unix 시스템
4.2 시작하기 /bin/sh sh 명령어 : 스크립트나 터미널로부터 수동적 호출 가능 대화형 셸 : 시작시 자신의 홈 디렉토리에서 “.profile” 화일을 찾음. “.profile”의 존재 유무에 관계없이 prompt를 내보내고 사용자의 명령을 기다림 비대화형 셸: 어떤 시작 화일도 읽지 않음 Unix 시스템
4.3 변수 변수의 생성 및 할당 (‘=‘전후에 빈칸 없게) {name=value}+ 변수가 존재하면 새로운 값으로 바꾸고, 존재하지 않으면 자동적으로 만들어짐. 공백은 “ ” 로 . (예) $ Name = meeyoung age=20 $ echo $Name is $age meeyoung is 20 $ name=Mee Young Sung .... error 문자열은 따옴표(“ “)로 표시 $ name=“Mee Young Sung” Unix 시스템
4.3 변수 변수로의 접근 $name : name의 값으로 대치 (예) $ verb=sing ...변수할당 $echo I like $verbing ... verbing 변수는 없다 I like $echo I like ${verb}ing ...성공 I like singing Unix 시스템
4.3 변수 4.3 변수 변수로의 접근 ${name-word} : 설정 되었으면 name의 값으로 대치, ${name+word} : name이 설정되었을 때 word만 대치 (예) $ startData=${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 is set’} ...조건부 메시지 #2 Unix 시스템
4.3 변수 4.3 변수 변수로의 접근 ${name=word} : name이 설정되지 않았으면 word를 할당하고 name의 값으로 대치 ${name?word} : name이 설정되지 않았으면 word는 표준 에러 채널로 표시되고 그 셸은 종료. (예) $ echo x = ${x=10} ...디폴트 값 할당 x=10 $ value=${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 ‘} … 설정 Unix 시스템
4.3 변수 표준 입력으로부터 변수 읽기 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 Unix 시스템
4.3 변수 echo C shell에서 Bourne shell에서 $ echo –n {string}* 모든 명령어 인자(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 \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” Unix 시스템
4.3 변수 4.3 변수 변수의 범위 전환 export {variable}+ 환경변수로 범위 전환시키도록 명시된 변수들을 표시 환경변수는 대문자 사용 (예) $ export .... 어떤 변수도 명시되지 않으면 모든 변수들의 목록이 나타남 export TERM $ DATABASE=/dbase/db .... 지역변수 생성 $ export DATABASE $ export .... export에 더해졌음 export DATABASE Unix 시스템
4.3 변수 4.3 변수 변수의 범위 전환 … dir= ~mysung/2003unixlinux/lecture/shellprog $ env {variable = value}*[command] command 실행을 위하여 지정된 환경변수에 값을 할당 (예) $ env .… 환경을 표시 PATH=/opt/inprise/vbroker/bin:/bin:/usr/bin:/usr/sbin:/usr/ucb:/usr/5bin:/usr/etc:/usr/lib:/usr/bin/X11:/usr/lib/X11:/usr/local/bin:/usr/local:/usr/openwin/bin:/etc:. HOME=/export/home/mysung LOGNAME=glass SHELL=/bin/csh TERM=ansi USER=mysung … dir= ~mysung/2003unixlinux/lecture/shellprog $ env PATH=$dir a.out Unix 시스템
4.3 변수 4.3 변수 읽기 전용 변수 readonly {variable}+ (cf) 환경변수로 전환된 변수의 읽기 전용 상태는 상속되지 않음 (예) $ password=nicechej ...지역변수의 할당 $ echo $password nicechej $ readonly password ...보호(수정방지) $ readonly readonly password ... 모든 readonly 변수 나열 $ password=chej ...변수 수정시도 password : is read only ... error Unix 시스템
4.3 변수 미리 정의된 지역 변수 이름 값 $@ $# $? $! $_ 모든 위치 매개 변수의 개별적으로 인용된 목록 위치 매개 변수의 수 마지막 명령의 반환값 마지막 후면 명령의 프로세스 id 명령 줄로 부터 혹은 내장 명령어 set(나중에 설명)에 의해 할당된 현재 셸 옵션 Unix 시스템
4.3 변수 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 Unix 시스템
4.3 변수 미리 정의된 환경변수 셸 시작 파일의 실행 이 름 값 $IFS Bourne 셸, Korn 셸: $ . .profile C 셸 : % source .cshrc 이 름 값 $IFS 셸이 명령어를 실행하기 전 명령 줄을 토큰화 시키는 경우, 설정된 문자를 분리자로 사용. 공백, tab, newline문자를 포함 $PS1 명령 라인 프롬프트 형태를 제어하며 디폴트로 $를 갖음. 명령줄 프롬프트를 변경하려면 $PS1을 새로운 형태로 지정. $PS2 더 많은 입력이 셸에 의해 요구될 때 명령 줄의 보조 프롬프트 형태를 제어, 디폴트로 >을 갖음. 프롬프롬트를 변경시 새로운 형태로 지정해 준다. IFS: Input Field Separators PS1: Prompt String 1 PS2: Prompt String 2 Unix 시스템
4.3 변수 4.3 변수 (예) $ PS1=“sh ? ” ...새로운 주 프롬프트 설정 sh? oldIFS=$IFS …IFS의 이전 값을 기억 sh? IFS=“:” …단어 분리자를 콜론으로 변경 /* Solaris 9, Linux에서는 적용되지 않음 */ sh? ls:*.c …실행 성공! badguy.c open.c trunc.c writer.c sh? String=“a long\ …긴 문자열을 할당 > string” …”>”는 보조 프롬프트 sh? PS2=“??? ” …보조 프롬프트 변경 ??? string” …”???”는 새로운 보조 프롬프트 Unix 시스템
= \> \>= \< \<= != 4.4 산술 계산 expr expression expression의 요소들은 반드시 공백으로 분리되어야 한다. 기타 연산자 (substr, index, length) 지원하지 않음 연산자 의미 \* / % + - = \> \>= \< \<= != \& \| : 곱셈, 나눗셈, 나머지 덧셈, 뺄셈 비교 연산자 논리적 and 논리적 or 문자열 matching Unix 시스템
4.4 산술계산 4.4 산술 계산 (산술 및 논리 연산 예) expression의 요소들은 반드시 공백으로 분리되어야 한다. $ x=l ... x의 최초값 $ x= `expr $x + l` ... x값 증가 $ echo $x 2 $ x=`expr 2 + 3 \* 5` ... * 계산 후 +계산 17 $ echo `expr \( 2 + 3 \) \* 5` ...\( \) 먼저 계산 25 $ echo `expr \( 4 \> 5 \)` ….4 > 5 ? $ echo `expr \( 4 \> 5 \) \| \( 6 \< 7 \)` ….4 > 5 또는 6 > 7? 1 (문자열 matching 연산 예) $ echo `expr “$USER” : ‘.*’` ….일치하는 문자열 길이 (정규 표현식만) 또는 $ echo `expr match “$USER” : ‘.*’` ….일치하는 문자열 길이 (정규 표현식만) 6 (cf.) $ echo `expr “USER” : ‘.*’` Unix 시스템
4.5 조건식 test expression 또는 [ expression ]… 괄호는 반드시 공백으로 둘러싸여야 함 test 명령의 옵션 [교재 p172 참조] Parentheses : \( \) 논리 연산 : ! , -a , -o 문자열 : -z , -n , = , != 숫자 : -eq , -ne , -gt , -ge , -lt , -le 파일 : -r , -w , -x , -f , -d , -s Unix 시스템
4.6 제어구조 case-in-esac case expression in pattern { | pattern }* ) list 패턴에 대응하는 것을 찾아 그 패턴의 명령들을 실행하는 다중 선택형식. expression은 문자열로 계산되는 식이고, pattern은 대표문자를 포함할 수 있음 case expression in pattern { | pattern }* ) list ;; esac Unix 시스템
4.6 제어구조 Unix 시스템 (예) $ 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 case $reply in "1") date ;; "2"|"3") pwd "4") stop=1 *) # default. echo illegal choice # error. esac done Unix 시스템
4.6 제어구조 4.6 제어구조 for-do-done for name [ in { word } * ] do list done 단어 리스트안의 각 맴버에 대해 명령의 집합을 한번씩 실행 for name [ in { word } * ] do list done Unix 시스템
4.6 제어구조 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 Unix 시스템
4.6 제어구조 4.6 제어구조 If-then-fi if list1 then list2 elif list3 ... elif는 여러번 반복가능함 then list4 else list5 ...else는 1번 이하 발생함 fi Unix 시스템
4.6 제어구조 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 Unix 시스템
trap [ [ command ] { signal } + ] 4.6 제어구조 trap 번호가 붙여진 signal을 받을 때마다 셸에게 command 를 실행 하도록 지시. 여러개의 signal이 받아들여지면 번호순으로 trap됨 signal 번호 0이 지정되면, 셸이 종료(exit)됐을 때 command가 실행됨[신호는 교재 497 참조] (예) $ cat trap.sh trap ‘echo Control-C; exit 1’ 2 while : do echo infinite loop sleep 2 done # 2(interrupt)신호가 수신되면 ‘ ’로 둘러싸인 명령어가 실행됨 trap [ [ command ] { signal } + ] Unix 시스템
메타문자(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 (원래대로 설정, 제어 문자 할당은 제외) Unix 시스템
4.6 제어구조 4.6 제어구조 until-do-done until list1 do list2 done list1의 명령어를 실행하고 참이나 0이 아닌 값을 반환할 때까지 list2의 명령을 실행함 until list1 do list2 done Unix 시스템
4.6 제어구조 4.6 제어구조 (예) $ cat until.sh x=1 until [ $x -gt 2 ] ...$x가 2보다 크면 참 do echo x = $x x = ‘expr $x + 1 ’ done $ until.sh x = 1 x = 2 Unix 시스템
4.6 제어구조 4.6 제어구조 while list1 do list2 done while-done list1의 의 조건이 만족되는 동안 list2의 명령을 반복 실행함 while list1 do list2 done Unix 시스템
4.6 제어구조 4.6 제어구조 (예) $ cat while.sh x=1 while [ $x -le 2 ] ...$x가 3보다 작으면 참 do echo x = $x x = ‘expr $x + 1 ’ done $ while.sh x = 1 x = 2 Unix 시스템
4.6 제어구조 4.6 제어구조 track [-ncount] [-tpause] userId 지정된 사용자의 로그인과 로그아웃 세션을 감시한다. Pause로 명시된 매초마다 시스템을 검색하여 현재 시스템에 들어와 있는 사용자의 목록을 만든다. count번의 검색이 완료될 때까지 수행 디폴트로 pause는 10초, count는 100번의 검색임 Unix 시스템
track pause=10 loopCount=100 error=0 for arg in $* do case $arg in # pause=`expr substr $arg 3 10` ;; -n*) # loopCount=`expr substr $arg 3 10` *) user=$arg esac done if [ ! "$user" ] then error = 1 fi if [ $error -eq 1 ] cat << ENDOFERROR usage: track [-n*] [-t*] userId ENDOFERROR exit 1 trap 'track.cleanup $$; exit $exitCode' 0 # exit trap 'exitCode=1; exit' 2 3 # INT/QUIT echo –n > .track.old.$$ count=0 while [ $count -lt $loopCount ] do who | grep $user | sort > .track.new.$$ diff .track.new.$$ .track.old.$$ | sed -f track.sed > .track.report.$$ if [ -s .track.report.$$ ] then echo track report for ${user}: cat .track.report.$$ fi mv .track.new.$$ .track.old.$$ sleep $pause count=`expr $count + 1` done Unix 시스템
track $ cat track.cleanup echo stop tracking rm -f .track.old.$1 .track.new.$1 .track.report.$1 $ cat track.sed # p326 sed 참조 /^[0-9].*/d /^---/d s/^</login/ s/^>/logout/ Unix 시스템
diff 교재 p296 참조 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 < 첫 번째 파일에서 치환되어야 할 줄 --- > 치환을 위하여 사용되어야 할 두 번째 파일 의 줄 Unix 시스템
sed 교재 p326 참조 Sed 편집 명령 만일 주소가 명시되어있지 않으면 모든 줄에 대하여 적용 스트림 편집, 하나 이상의 화일을 스캔하여 특정 조건에 맞는 모든 줄을 편집한다. 단순 반복 편집에 유용하다. 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를 첨가 만일 주소가 명시되어있지 않으면 모든 줄에 대하여 적용 Unix 시스템
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 → '<<'를 줄의 맨 앞에, '>>'를 줄의 맨 뒤에 삽입함 Unix 시스템
4.8 그 밖의 내장명령어 4.8 그 밖의 내장명령어 read 명령어 표준 출력에서 변수의 라인을 읽음 null 명령어 어떤 연산도 수행하지 않음 (null builtin ‘:’ 으로 표기하고 항상 참을 돌려 줌) set 명령어 변수나 명령 라인 매개 변수를 지정하거나 모든 변수를 표시 set -ekntuvx { arg }* Unix 시스템
set set 옵션 (교재 p184 표 참조) $ 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 “$@” Unix 시스템
set -x 명령 행 옵션으로 실행되는 디버깅 기능 쉘 명령 앞에서 변수 배정 정의하면 그 명령으로 변수 값이 export 됨 $ cat set.sh set -vx a.c ls $1 set - echo $notset echo goodbye $USER set -u $ 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 Unix 시스템
4.9 개선점 4.9 개선점 Redirection: >&, 2>&, <&, <&-, >&-(표준출력 닫은 후 명령실행) 순차적 명령열: (cd /; pwd) 과 { cd /; pwd; } 서브셸에서 부모셸에서 … 반드시 빈칸과 ;으로 구분 4.10 명령줄 옵션 Bourne shell은 다음 명령 줄 옵션을 지원한다. 옵 션 의 미 -c string 명령 string을 실행하기 위해 셀 생성 -s 표준 입력으로부터 명령을 읽고 표준에러 채널로 메시지를 보내는 셀을 생성 -i SIGTERM, SIGINT, SIGQUIT 시그널이 모두 무시되는 것을 제외하면 –s옵션과 같은 대화형 셀을 생성 Unix 시스템
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 참조 Unix 시스템
과제 3…10월 22일(수)까지 교재 p188 연습문제 1: junk 유틸리티 작성 (p235~p237 참조) 이름, 주소, 전화번호로 검색이 가능한 전화번호부 유틸리티를 아래의 두 경우에 대하여 각각 작성 전화번호 데이터가 프로그램과 같은 파일 안에 있는 경우 (힌트: here document) 전화번호 데이터가 프로그램과 다른 파일 안에 있는 경우 완벽한 track 유틸리티 Borne shell version 작성 (스트링 추출은 sed나awk 참조: expr에서 substr 동작하지 않으므로) 6장 C 셸 과제 4의 본 셸 프로그램 (whatchfor, pick, checkmail) 코딩 및 실행 과제 제출 방법 Electrical Version : csmail.incheon.ac.kr (211.119.245.75)의 /home/mysung/2003unixlinux/classA (또는 classB) 에 자신의 학번으로 디렉토리 만들고 그 안에 복사 Paper Version : 종이에 소스와 실행 과정 및 결과 출력하여 제출 Unix 시스템
C 셸 버전 1 문제 1: 다음은 60초 마다 한번씩 mary가 로그인 했는지 조사하는 본 셸 프로그램 watchfor이다. 이 프로그램을 참조하여 매개변수로 입력된 사람이 로그인 했는지 조사하는 C 셸 버전을 작성하되, 한 사람 이상도 한번에 조사할 수 있도록 하라. (p157 egrep 참조) $ cat watchfor PATH=/bin:/usr/bin until who | grep mary do sleep 60 done Unix 시스템
C 셸 버전 2 문제 2: 다음의 pick은 매개변수로 입력된 인수들을 취사선택하는 본 쉘 프로그램이다. 이 프로그램을 코딩하여 실행해 보고, 명령 줄에 아무것도 없으면 표준 입력으로부터 인수를 읽는 pick의 C 셸 버전을 작성하라. 빈 칸을 적절히 다루고, q 도 잘 동작하도록 하라. $ cat pick PATH=/bin:/usr/bin for i do echo “$i? \c” read response case $response in y*) echo $i ;; q*) break esac done Unix 시스템
C 셸 버전 3 문제 3 : 다음의 checkmail 본 쉘 프로그램을 코딩하여 실행해 보고 C 셸 버전으로 수정하되 메시지에 메일을 보낸 사람의 이름이 나타나도록 하고 우편함 파일(MAIL)이 존재하지 않더라도 잘 동작하도록 하라. $ cat checkmail PATH=/bin:/usr/bin MAIL=/var/mail/`logname` t=${t-60} 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 시스템
7.8 프로그램 가능한 텍스트 처리 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 시스템
7.8 프로그램 가능한 텍스트 처리 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 시스템
7.8 프로그램 가능한 텍스트 처리 입력 줄의 항목 접근 BEGIN과 END - $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 Unix 시스템
7.8 프로그램 가능한 텍스트 처리 연산자 사용자 정의 변수의 사용 - 초기값: null string 또는 정수 0 $ cat awk3 #2,3번째 줄에 대하여 항목 인쇄 NR > 1 && NR < 4 print NR, $1, $3, $NF $ 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 Unix 시스템
7.8 프로그램 가능한 텍스트 처리 내장함수 이용 가능 제어구조(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 Unix 시스템