UNIX 및실습 11 장보충 awk (1) 1
awk 란? 데이터조작및보고서생성에사용되는유닉스프로그래밍언어 개발자세사람 (Alfred Aho, Peter Weinberger, Brian Kernighan) 의이름첫글자로조합 nawk : awk 의최신버전 gawk : GNU 버전 명령으로간단한조작을할수있으며, 큰규모의응용프로그램작성도가능 쉘스크립트와소규모데이터베이스관리에서빼놓을수없는유용한툴 사용자가지정한패턴검색이나특별한작업을수행하기위해파일 ( 또는입력 ) 을줄단위로조사 특정작업이없는패턴의경우패턴과일치된모든줄이출력되고, 특정작업이지정된경우해당작업을수행한결과출력 2
awk 형식 (1) awk 명령과따옴표로묶은 ( 혹은파일에있는 ) 프로그램명령, 입력파일명으로구성 gawk pattern filename gawk {action} filename gawk pattern {action} filename 예제파일 (employees) 1 2 3 Tom Jones 4424 5/12/66 543354 Mary Adams 5346 11/4/63 28765 Sally Chang 1654 7/22/54 567534 Billy Black 1683 9/23/44 335678 실행예 [kgu@lily ~]$ gawk '/Mary/' employees Mary Adams 5346 11/4/63 28765 [kgu@lily ~]$ gawk '{print $1}' employees Tom Mary Sally Billy [kgu@lily ~]$ gawk '/Sally/ {print $1, $2}' employees Sally Chang 3
awk 형식 (2) 파이프연결 command gawk pattern filename command gawk {action} filename command gawk pattern {action} filename 4 5 실행예 [kgu@lily ~]$ df gawk '$4 > 3000000' Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/vg_lily-lv_root 51606140 14985396 33999304 31% / /dev/mapper/vg_lily-lv_home 182104276 28573372 144280500 17% /home [kgu@lily ~]$ last gawk '/kgu/ {print $3}' 220.68.173.204 59.3.145.29 203.232.252.170 220.68.173.204 220.68.173.201 203.232.252.170 220.68.173.204 203.232.252.111 4
출력형식지정 (1) awk 명령의동작부분은중괄호 { } 로묶는다 예제 6 동작부분이생략되어있으면기본동작수행 print 는특별한서식이지정되지않은간단한출력에사용 - 복잡한서식이필요한경우 printf 와 sprintf 사용 [kgu@lily ~]$ date 2013. 05. 20. ( 월 ) 08:46:06 KST [kgu@lily ~]$ date gawk '{print "Month: " $2 "\nyear: " $1}' Month: 05. Year: 2013. Escape Sequences 7 \b 백스페이스 \f Form feed \n New line \r Carriage return \t Tab \047 8 진수 47(ASCII 코드 ) \c c 를문자자체로표현 ( 예 : \) [kgu@lily ~]$ gawk '/Sally/ {print "\t\thave a nice day, " $1, $2 "!"}' employees Have a nice day, Sally Chang! OFMT 변수 : 숫자서식을지정하는특수변수 8 [kgu@lily ~]$ gawk 'BEGIN { OFMT="%.2f ; print 1.23456, 1.23E-2}' 1.23 0.01 5
printf 9 출력형식지정 (2) [kgu@lily ~]$ echo "UNIX" gawk ' {printf " %-15s \n", $1}' UNIX [kgu@lily ~]$ echo "UNIX" gawk ' {printf " %15s \n", $1}' UNIX 10 [kgu@lily ~]$ gawk '{printf "The name is: %-15s ID is %8d\n", $1, $3}' employees The name is: Tom ID is 4424 The name is: Mary ID is 5346 The name is: Sally ID is 1654 The name is: Billy ID is 1683 6
파일에서 awk 명령사용 -f 옵션으로파일지정 11 [kgu@lily ch11_awk]$ cat awkfile /^Mary/{print "Hello, Mary!"} {print $1, $2, $3} [kgu@lily ch11_awk]$ gawk -f awkfile employees Tom Jones 4424 Hello, Mary! Mary Adams 5346 Sally Chang 1654 Billy Black 1683 7
레코드와필드 12 13 레코드구분자 : CR(Carriage Return) $0 : 전체레코드 NR : 레코드번호를저장하는내장변수 [kgu@lily ch11_awk]$ gawk '{print NR, $0}' employees 1 Tom Jones 4424 5/12/66 543354 2 Mary Adams 5346 11/4/63 28765 3 Sally Chang 1654 7/22/54 567534 4 Billy Black 1683 9/23/44 335678 각레코드는필드구분자 ( 보통화이트스페이스 ) 로구분된필드들로구성 NF : 필드수기록하는내장변수 [kgu@lily ch11_awk]$ gawk '{print NR, $1, $2, $5, NF}' employees 1 Tom Jones 543354 5 2 Mary Adams 28765 5 3 Sally Chang 567534 5 4 Billy Black 335678 5 필드구분자를변경하고자하는경우 F 옵션사용 ( 둘이상의경우 [ ] 이용 ) 14 [kgu@lily ch11_awk]$ gawk -F: '/kgu/ {print NR, $1, NF}' /etc/passwd 52 kgu 7 [kgu@lily ch11_awk]$ gawk -F'[ :\t]' '/kgu/ {print NR, $1, NF}' /etc/passwd 52 kgu 7 8
패턴과동작 패턴은정규표현식이거나참, 거짓의결과를갖는조건표현식혹은이둘의조합 15 16 [kgu@lily ch11_awk]$ gawk '/Tom/' employees Tom Jones 4424 5/12/66 543354 [kgu@lily ch11_awk]$ gawk '$3 < 4000' employees Sally Chang 1654 7/22/54 567534 Billy Black 1683 9/23/44 335678 동작은중괄호 { } 로묶여있으며, ; 으로구분하거나개행문자로각줄에하나씩둘수있음 pattern { action statement; action statement; etc. } 또는 pattern { } action statement action statement 9
정규표현식 (1) awk 정규표현식메타문자 메타의미메타의미 ^ 행의시작지시자 [ABC] [ ] 사이의문자집합중하나에대응 $ 행의끝지시자 [^ABC] [ ] 사이의문자집합에속하지않는한문자와 대응. 하나의문자와대응 [A-Z] A 부터 Z 사이의문자집합중하나에대응 * 선행문자와같은문자의 0 개혹은임의개수에대응 A B A 나 B 중하나에대응 + 선행문자와같은, 하나이상의문자에대응 (AB)+ 하나이상의문자셋 AB 와대응? 선행문자와같은, 0 개혹은하나의문자에대응 \* 문자로서의 * & 검색열을저장하여치환열에서사용 지원되지않는메타문자 \< >\ : 단어지시자 \( \) : 역참조.\{ \} : 반복 10
match 연산자 : ~ 정규표현식 (2) 특정레코드나필드내에서일치하는패턴이존재하는지검사 17 18 [kgu@lily ch11_awk]$ gawk '$1 ~ /[Bb]illy/' employees Billy Black 1683 9/23/44 335678 [kgu@lily ch11_awk]$ gawk '$1 ~ /ly$/' employees Sally Chang 1654 7/22/54 567534 Billy Black 1683 9/23/44 335678 POSIX 문자항목 ( 대괄호문자클래스 ) [:alnum:] 알파벳과숫자 [:graph:] 공백이아닌문자 [:space:] 공백문자 [:alpha:] 알파벳 [:lower:] 소문자 [:upper:] 대문자 [:cntrl:] 제어문자 [:print:] [:graph:] 와유사하나공백포함 [:xdigit:] 16진수 [0-9a-fA-F] [:digit:] 숫자 [:punct:] 구두점 11
스크립트파일안의 awk 명령 예제 19 [kgu@lily ch11_awk]$ cat info # Script name: info # This is a comment. /Tom/ {print "Tom's birthday is " $4} /Mary/ {print NR, $0} /^Sally/ {print "Hi, Sally, " $1 " has a salary of $" $5 "."} # End of info [kgu@lily ch11_awk]$ gawk -f info employees Tom's birthday is 5/12/66 2 Mary Adams 5346 11/4/63 28765 Hi, Sally, Sally has a salary of $567534. 12
관계연산자 C 프로그래밍참조 조건식 비교식 20 조건식 1? : 구문 2 : 구문 3 [kgu@lily ch11_awk]$ gawk '{max= ($1 > $2)? $1: $2; print max}' filename 산술계산 (+,-,*,/,%,^( 지수 )) 논리연산지 (&&,,!) 범위패턴 13
변수 초기화와강제변환 name= Nancy x++ number = 35 name + 0 : 문자열을숫자로강제 변환 number : 숫자를문자열로강제변환 대입연산자 : =, +=, -=, *=, /=, %=, ^= 21 예 : a ^= 5 (a = a^5) 내장변수 ARGC : 명령줄매개변수개수 ARGV : 명령줄매개변수배열 FILENAME : 현재입력파일이름 FNR : 현재파일의레코드수 FS: 필드구분자 NF : 현재레코드의필드개수 NR : 지금까지레코드개수 OFMT : 숫자를위한출력서식 OFS : 출력필드구분자 ORS : 출력레코드구분자 RLENGTH : match 함수가찾은일치하는문자열길이 RS : 입력레코드구분자 RSTART : match 가찾은문자열위치 SUBSEP : 배열요소구분자 [kgu@lily ch11_awk]$ gawk -F'[ :\t]' '$8 == "CA" { $8 = "California"; print}' datebook Betty Boop 245-836-8357 635 Cutesy Lane, Hollywood, California 91464 6/23/23 14500 Tommy Savage 408-724-0140 1222 Oxbow Court, Sunnyvale, California 94087 5/19/66 34200 14
BEGIN 패턴과 END 패턴 BEGIN 패턴 입력파일을처리하기전에수행해야하는동작들지정 일반적으로 OFS, RS, FS 등과같은내장변수값을변경하거나사용자정의변수초기화, 헤더나제목출력에이용 END 패턴 모든입력줄처리가끝난후처리 처리한레코드수나계산결과출력 15
입력리다이렉션 (getline) 현재처리중인입력파일이아닌, 표준입력이나파이프, 또는다른파일로부터입력을받기위해사용 22 23 [kgu@lily ch11_awk]$ gawk 'BEGIN {"date" getline d; print d}' datebook 2013. 05. 20. ( 월 ) 10:56:23 KST [kgu@lily ch11_awk]$ gawk 'BEGIN {"date" getline d; split(d, darr); print darr[3]}' datebook 20. 24 [kgu@lily ch11_awk]$ cat awk_file2 BEGIN {printf "What is your name? " ; 가아닌새로운줄로 getline name < "/dev/tty" 명령구분가능 } $1 ~ name {print "Found " name " on line ", NR "." print $0 } END {print "See ya, " name "."} [kgu@lily ch11_awk]$ gawk -f awk_file2 /etc/passwd What is your name? kgu Found kgu on line 52. kgu:x:1000:1000:kgu:/home/kgu:/bin/bash See ya, kgu. 16
실습 (awk 를포함한모든유틸리티사용 ) 17 don_data Mike Harrington:(510) 548-1278:250:100:175 Christian Dobbins:(408) 538-2358:155:90:201 Susan Dalsass:(206) 654-6279:250:60:50 Archie McNichol:(206) 548-1348:250:100:175 Jody Savage:(206) 548-1278:15:188:150 Guy Quigley:(916) 343-6410:250:100:175 Dan Savage:(406) 298-7744:450:300:275 Nancy McNeil:(206) 548-1278:250:80:75 John Goldenrod:(916) 348-4278:250:100:175 Chet Main:(510) 548-5258:50:95:135 Tom Savage:(408) 926-3456:250:168:200 Elizabeth Stachelin:(916) 440-1763:175:75:300 이름, 전화번호, 지난 3 개월간기부한금액 Name Phone 1st 2nd 3rd Sum Mike Harrington (510) 548-1278 250 100 175 525 Christian Dobbins (408) 538-2358 155 90 201 446 Susan Dalsass (206) 654-6279 250 60 50 360 Archie McNichol (206) 548-1348 250 100 175 525 Jody Savage (206) 548-1278 15 188 150 353 Guy Quigley (916) 343-6410 250 100 175 525 Dan Savage (406) 298-7744 450 300 275 1025 Nancy McNeil (206) 548-1278 250 80 75 405 John Goldenrod (916) 348-4278 250 100 175 525 Chet Main (510) 548-5258 50 95 135 280 Tom Savage (408) 926-3456 250 168 200 618 Elizabeth Stachelin (916) 440-1763 175 75 300 550 1. 첫번째달에 100 달러이상기부한사람의이름과첫번째달기부금액을출력 (50 점 ) 2. 두번째달에 100 달러이하기부한사람의이름과전화번호를출력 (50 점 ) 3. 3 개월간 500 달러이상기부한사람의이름출력 (50 점 ) 4. 3 개월간평균 150 달러이상기부한사람이름출력 (50 점 ) 5. 레코드번호와이름, 3 개월간기부한총금액출력 (50 점 ) 6. 표형식으로칸을맞추어출력 (printf 사용 ) (200 점 ) 7. 처음에제목을출력하고, 각레코드번호, 이름, 각달의기부금액, 3 개월합계를표형식으로칸에맞추어출력, 마지막줄에는전체레코드수와기부총액을출력 (300 점 ) 8. 3 개월간기부한총금액을기준으로정렬하여이름, 3 개월간기부한총금액출력 (300 점 )