/
awk / shell programming awk / shell programming

awk / shell programming - PowerPoint Presentation

calandra-battersby
calandra-battersby . @calandra-battersby
Follow
414 views
Uploaded On 2016-04-26

awk / shell programming - PPT Presentation

김선영 sunyzerogmail dotcom 버 전 20141222 가메 출판사 httpwwwkamecokr 인사이트 httpbloginsightbookcokr 저자블로그 httpsunyzerotistorycom ID: 293738

print awk txt printf awk print printf txt function 010 practice account var john pattern gensub posix con sunyzero file cat str

Share:

Link:

Embed:

Download Presentation from below link

Download Presentation The PPT/PDF document "awk / shell programming" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.


Presentation Transcript

Slide1

awk / shell programming

김선영sunyzero@gmail(dot)com버 전: 2014-12-22

가메

출판사

http://www.kame.co.kr

인사이트

http://blog.insightbook.co.kr

저자블로그

http://sunyzero.tistory.comSlide2

awksyntax, practiceSlide3

What is awk?설계자인 Aho. Weinbrger, Kernighan

의 머릿글자에서 유래/ɔːk/ 라고 읽는다.공식적으로 "패턴 검색과 처리언어"라고 정의독자적인 처리 문법과 언어 구성을 갖추고 있음expr, grep, sed의 모든 기능을 포함하고 있음grep, sed로 처리가 불가능하다면 awk를 사용gawk (GNU awk) - 확장된 기능 제공이 강의는 gawk를 기준으로 작성되었으나 대부분의 표현식은 POSIX awk에서도 잘 작동합니다.Slide4

awk commandawk의 실행 방법

awk script는 single quotes로 묶는다. Why?GNU awk(gawk)에서 POSIX로 작동하려면 --posix 옵션을 준다.awk [-F

필드구분자

] '

스크립트코드

' <

처리할파일

>...

awk [-F

필드구분자

] -f <awk스크립트파일> <처리할파일>...

실행 명령어만 알아도 절반은

먹고 들어가는 법이다

!Slide5

awk CLIdata file : account.txt

# UNIX ACCOUNT : No.00704sunyzero:Sunyoung Kim:1600:AA-1342R:010-2007-8080:19991222ppan:Peter Pan:1200:CC-0100R:010-3593-1277:19921202clyde47:John Smith:650:CC-1106R:010-6532-1004:20000123banaba:John Kennis:1100:CA-0971R:010-4321-1234:20000123

jamtaeng:Jambo

Park:880:AD-1000R:010-6420-3578:19970802

$

awk -F : '{print $1, $4;}' account.txt

# UNIX ACCOUNT

sunyzero AA-1342R

ppan CC-0100R

clyde47 CC-1106R

banaba CA-0971Rjamtaeng

AD-1000R

-F : # field separator

$1, $4 # fields

print

명령은 자동 개행

!Slide6

awk script filedata file : account.txt

$ cat pr_1a4.awk{ print $1, $4 }

$

awk -F : -f pr_1a4.awk account.txt

# UNIX ACCOUNT

sunyzero AA-1342R

ppan CC-0100R

clyde47 CC-1106R

banaba CA-0971R

jamtaeng

AD-1000R-f file # script filenamecomma의 역할은? print $1 $4로 해보자Slide7

awk script block조건/

패턴이 true일 때 { command; ... } 실행[ condition or

pattern

] {

command;

...

}

$

awk

-F : 'NR>1 { printf "%s(%s)\n",$1,$2 }' account.txtsunyzero(Sunyoung Kim)ppan(Peter Pan)clyde47(John Smith)banaba(John Kennis)jamtaeng(Jambo Park)NR>1 # Line numberprintf # formatingSlide8

printfC-style formatting

%[flag][x][.y]cflag플래그 지정

: -, 0, '

등을 지정할 수 있음

.

x

최소 필드 너비

(min. field width)

를 지정

.y

정밀도 지정

c

변환형 지정

: s,d,f,s,c ...

등등을 지정할 수 있음

.

flag

설명

-

왼쪽으로 정렬

0

숫자 출력시 빈공백 부분을

0

으로 채움

'

숫자 출력시 천

(thousand)

단위로 점을 찍을때 사용

홀 따옴표에 주의Slide9

printf : single quotes홀 따옴표 사용 주의

결론 : escape가 필요하다.하지만 %\'10d으로 하면 single quotes로 인해escape전과 다를 바가 없다.Slide10

printf : single quotes (con't)escape

를 위한 블록 분리1000단위 출력이 실패하는 경우LC_LOCALE이 설정된 경우(or LANG의 영향)홀 따옴표에 주의(쌍 따옴표 아님

)Slide11

printf: conversion (C-style)

변환형설명d, i10진수 정수형

u

10

진수 양의 정수형

o

8

진수 양의 정수형

x, X

16

진수 양의 정수형f, F

실수형

e, E

실수형

(

scientific notation

으로 지정된

)

e.g. 1.23456e+05

c

숫자인 경우

ASCII

코드로 변환하여 문자

1

개 출력

문자열인 경우 맨앞 한개의 문자만 출력

s

문자열 출력Slide12

printf: practice

숫자 출력 예제Slide13

printf: practice (con't)

문자열 출력 예제Slide14

awk fieldfield 선택

awk variablestring, integer, real number 모두 지원$ awk -F: 'NR>1 {var

=$2;$2=$3;$3=var; print}'

account.txt

sunyzero 1600 Sunyoung Kim AA-1342R 010-2007-8080 19991222

ppan 1200 Peter Pan CC-0100R 010-3593-1277 19921202

clyde47 650 John Smith CC-1106R 010-6532-1004 20000123

banaba 1100 John Kennis CA-0971R 010-4321-1234 20000123

jamtaeng 880 Jambo Park AD-1000R 010-6420-3578

19970802

2th, 3th 필드의 스왑Slide15

Pratice조건 적용하여 출력해보자.

$ awk 'NR>1 {printf "%d:%s\n",NR-1,$1}' account.txt1:sunyzero:Sunyoung2:ppan:Peter

3:clyde47:John

4:banaba:John

5:jamtaeng:Jambo

$

awk -F: 'NR>1 {printf "%d:%s\n",NR-1,$1}' account.txt

1:sunyzero

2:ppan

3:clyde47

4:banaba5:jamtaengSlide16

awk pattern패턴 형식

/regular expression/relational expressionpattern && pattern

pattern

|| pattern

pattern

? pattern : pattern

(

pattern)

!

pattern

pattern1, pattern2pattern { .... }

range

패턴은 데이터 파일을 처리하는데 유용하다

.Slide17

pattern: REGEX/REGEX/ 를 이용하여 조건 사용

$ awk '/C[A-Z]-[0-9A-Z]+/ {print}' account.txtppan:Peter Pan:1200:CC-0100R:010-3593-1277:19921202clyde47:John Smith:650:CC-1106R:010-6532-1004:20000123

banaba:John Kennis:1100:CA-0971R:010-4321-1234:20000123

$

awk -F: '$

4 ~ /C[A-Z]-[0-9A-Z]+/ {print}' account.txt

ppan:Peter Pan:1200:CC-0100R:010-3593-1277:19921202

clyde47:John Smith:650:CC-1106R:010-6532-1004:20000123

banaba:John Kennis:1100:CA-0971R:010-4321-1234:20000123Slide18

operator

OperatorDescriptionExample

==, !=

equality operator, not equal to

$1=="Fred", $4!=NF

<

less than

$1<$3

<==

less than or equal to

$1<=$1+NR

>

greater than

$10>100

?:

Condition operator (equal to C)

~

contain regular expressions (match)

$4~/LOC/ , $9~/[A-Z]/

!-

Dose not contain regular expression

$9!~/..[a-z]/Slide19

operator (con't)blank line을 제외하고 첫번째 필드가

100보다 큰 경우범위 연산을 사용하는 경우$ awk '($0 !~ /^$/) && ($1 > 100) {print $0}' datafile.txt

$

awk '(

NR == 3),(NR ==

10)'

/etc/passwdSlide20

operator (con't)다양한 패턴 조합이 가능하다.

데이터 파일 내부에 start, end를 명시하는 comment line이 있다면 패턴으로 걸러내서 읽을 수 있다./^[^#]+/ { print }/^[^#]+/ || $0 !~ /^$/

{ print }

/^#start data/,/^#end data/

{ print }

(NR == 5),/^#end of file/

{ print }Slide21

BEGIN, ENDBEGIN연산이 일어나기 에 수행

initialization, pre-processing 작업END연산이 끝난 뒤에 수행주로 출력을 수행한다.BEGIN { action }pattern { action }

...

END { action }Slide22

BEGIN, END (con't)BEGIN 사용 방식

END 사용 방식$ awk 'BEGIN {FS=":"} (NR == 3),(NR == 10)' /etc/passwd

$

awk 'END { print NR }' /etc/passwd

34

$

wc -l /etc/passwd

34 /

etc/passwdSlide23

BEGIN, END (con't)BEGIN, END를 이용한 계산

$ cat pi.awkBEGIN { print "Pi (numerical integration method)" }{ n_steps = $1; sz_step = 1.0/n_steps; sum=0.0; }END {

for (i=0; i<n_steps; i++) {

x = (i+0.5) * sz_step;

sum += 4.0/(1.0 + x*x);

}

printf("n_steps = %d, sz_step = %.8f\n", n_steps, sz_step);

printf("pi = %.8f, 4*atan(1) = %.8f\n", sz_step*sum, atan2(1,1)*4);

}

$

time echo 2000000 | awk -f pi.awkPi (numerical integration method)

n_steps = 2000000, sz_step = 0.00000050

pi = 3.14159265, 4*atan(1) = 3.14159265

real 0m0.546s

user 0m0.544s

sys

0m0.001s

atan2() - arc-tangent in radians angleSlide24

built-in var.

변수명의미

ENVIRON

환경 변수들을 모아둔 관계형 배열

ARGC

커맨드 라인 아규먼트의 갯수

ARGV

커맨드 라인 아규먼트의 어레이

FILENAME

문자열

=

현재 입력 파일명

FNR

현재

file

의 현재 레코드 번호

(

각 입력 파일에서

1

부터 시작한다

.)

FS

입력 필드

seperator

문자

(

기본값

=

공백

)

NF

현재 레코드의 필드 번호

NR

현재의 레코드 번호

(

모든 입력 파일을 통틀어

)

FIELDWIDTHS

FS

대신에 사용할 고정 필드 크기

(

구분자가 없는 데이터 처리시 사용한다

.)

OFMT

숫자를 위한 출력 포멧

(

기본값

= %.6g)

OFS

출력 필드

seperator (

기본값

=

스페이스

)

ORS

출력 레코드

seperator (

기본값

=

개행문자

)

RS

입력 레코드

seperator (

기본값

=

개행문자

)

SUBSEP

배열에 쓰는 첨자 구획 문자

RSTART

매칭 연산

(match function)

만족하는 문자열의 맨 앞부분

RLENGTH

매칭 연산

(match function)

만족하는 문자열의 길이

IGNORECASE

대소문자 무시

*

*

IGNORECASE

관련 함수

: gensub(),

gsub(), index(), match(), split

(), sub()Slide25

flow control

Flow control statementDesc.

if (conditional)

{

statement_list1}

[else

{

statement_list2}]

C-style if

while (conditional)

{statement_list}

C-style

while

for (init;condition;ctrl

)

{

statement_list}

C-style for loop

break

루프를 종료시키고 다음

statement

로 넘어가게 한다

.

continue

현재 위치에서 루프의 다음

iteration

으로 넘어가게 한다

.

next

현재

input line

에 대해서 남아있는

pattern

skip

exit

남아있는

input

을 모두

skip

한다

.

만일

END pattern

이 있다면

처리한 후

awk

를 종료시킨다

.Slide26

print , var control

print control statementprint [expr_list] [>file]

expr_list

에 있는

expression

stdout

이나 특정 파일로

리다이렉트 한다

.

file은 file descriptor를 사용한다.

printf format [,expr_list] [>file]

C

언어의

printf

문과

동일

포맷된

형식의

expression

을 보여준다

.

출력은

위와 같다

.

sprintf (format [,expression])

C

언어의

sprintf

처럼 버퍼에 리턴하기만 하고

,

출력하지

않는다. 변수에 저장할 때 사용한다.

assignment statement

variable=awk_expr

awk expr

에서 나온

expression

variable

에 할당한다

.

userdefined fd

3-19

까지 사용 가능하다

.

printf

default precision

6

자리이다

.Slide27

Practice합산 계산,

새로운 필드 할당$ cat score.txt#name:math1:math2:datastructure:algorithmJack,78,45,68,49Mick,77,32,86,67

Fred,95,55,85,62

Kim,88,42,85,60

$

awk

-F,

'NR>1 { $6

=$2+$3+$4+$5;

print $0 }'

score.txtJack 78 45 68 49 240Mick 77 32 86 67 262Fred 95 55 85 62 297Kim 88 42 85 60 275

$

awk

-F,

'$0 !~ /^#.*/ { $6=$2+$3+$4+$5; print $0 }'

score.txt

...생략...

6th field

는 새로 할당된 필드다

.Slide28

Practice (con't)2번째 과목의 평균 계산

$ cat avg.awk$0 !~ /^#.*/ { sum += $3 }END { printf "math2 avg = %.2f\n", sum/(NR-1) }$ awk -F, -f avg.awk score.txtmath2 avg = 43.50Slide29

PracticeSystem daemon의

Minor pagefault, RSS 계산$ cat chk_sysdaemon.sh#!/bin/bash

ps -eo user,uid,pid,ppid,sz,rss,vsz,min_flt,maj_flt,cmd |

awk '

BEGIN { n_ps=0; n_tot_minflt=0; n_tot_rss=0; }

($1 == "root") && ($4 == 1)

{ n_ps++; n_tot_minflt+=$8; n_tot_rss+=$6; }

END {

printf "-------- Daemon process monitor --------\n";

printf "Processes\tMin.PageFault\tTotalRSS\n";

printf "%9d \t %12d \t %7d\n", n_ps, n_tot_minflt, n_tot_rss;}'Slide30

functionlength(x)는

x의 길이를 리턴한다.$ awk -F: '(length($2)<11 && NR>1) {printf "%d:%s,%s\n",NR-1,$1,$2}' \

account.txt

2:ppan,Peter Pan

3:clyde47,John Smith

5:jamtaeng,Jambo ParkSlide31

function: string

function namedescription gsub(r,s[,t])

정규표현식

r

과 매치되는 문자열

t

s

로 대치한다

.

(t를 지정하지 않으면 $0 ; 문자열 자체가 변경되니 조심할 것!)

* return value :

대치에 성공한 패턴 개수

(

양수

)

index(str1,str2)

Returns the starting position of str2 in str1.

If str2 is not present in str1, then 0 is returned

length(str)

Returns the length of string str

match(s,r)

문자열

s

에서 정규표현식

r

과 매치되는 부분의 위치를 넘겨준다

split(str,array[,sep])

구분자

sep

를 기준으로

(default

space

)

문자열

str

배열로

변환

sprintf(fmt,awk_exp

)

Returns the values of awk_exp formatted as defined by

fmt

sub(r,s[,t])

정규표현식

r

과 매치되는 문자열

t

s

로 대치한다

.

gsub

와 다른점은

t

에서

r

과 매치되는 부분이

여러 개라

할지라도

처음

한 개만 대치한다는 것이다

.

* return value:

대치에 성공한 패턴 개수

(0

or 1)

* gawk

gsub, sub

general version

gensub

를 지원한다

.

* gawk

strtonum()

으로

base

진수로 표기된 문자열을 숫자로 변환할 수 있다

.

*

gsub (global sub)Slide32

function: string

function namedescription substr(str,start,length)

Returns a substring of the string str starting at position start for length characters

ex) substr("believe", 3, 5) == "lieve"

tolower(str)

문자열

str

을 모두 소문자로 바꾼다

toupper(str)

문자열

str

을 모두 대문자로 바꾼다Slide33

function: math

function description (angle은 모두 radian으로 쓴다)

int(x)

x

의 소수점 이하 값을 버린다

.

rand()

0

에서

1

사이의

random variable

을 취한다

.

srand(x)

rand

을 위해

x

를 새로운

seed

setting

(

특정값이나

새로운

랜덤 변수

발생시

사용

)

cos(x)

x

cosine값을 리턴sin(x)

x

sine

값을 리턴

atan2(x,y)

y/x

arc tangent

값을 리턴

exp(x)

e^x

의 값을 리턴

(

무리수

e

x

승 값

)

log(x)

log_e x

의 값을 리턴

(

자연로그

x

값을 리턴

)

sqrt(x)

음수가 아닌

x

의 루트값

(

the radical sign, value = x)Slide34

function: date, time

function description

systime()

UNIX epoch

timestamp

를 리턴한다

.

strftime([fmt [,

timestamp

]])

C-style strftime

$

awk 'BEGIN { print systime()

}'

1400908965

$

awk 'BEGIN { print strftime("%Y%m%d-%H%M%S %z") }'

20140524-143007 +

0900Slide35

Practice : function : substrsubstr - substring

$ cat contdata.txtB6011KR70053800010000003886390002340000002335000000000030310B6012KR70357600080000000082690003844000003843000000000000140

B6011KR70059300030000001237900014410000014400000000000007510

B6011KR70059300030000001238240014410000014400000000000007270

B6012KR70357600080000000126490003837000003836000000000000280

B6011KR7005380001

000000388663

0002340000002335000000000030310

$

awk 'substr($

0,6,12) == "KR7005380001" { print substr($0,18,12) }' \contdata.txt000000388639000000388663Slide36

Practice : function : matchPOSIX awk에서는

{n,m} 표현을 지원하지 않는다.--re-interval 옵션 : REGEX interval expression을 지원--re-interval 대신에 --posix 으로 실행해보자.gawk manual>>extensions in gawk Not in POSIX awk 참고

$

gawk --re-interval \

'match($0,/KR[0-9]{10}/) { print substr($0,RSTART+3,RLENGTH-6)

}' \

contdata.txt

005380

035760

005930

005930035760005380Slide37

Practice : function : gsub, sub, gensubsubstitution function

$ cat contdata.txtB6011KR70053800010000003886390002340000002335000000000030310B6012KR70357600080000000082690003844000003843000000000000140

B6011KR70059300030000001237900014410000014400000000000007510

B6011KR70059300030000001238240014410000014400000000000007270

B6012KR70357600080000000126490003837000003836000000000000280

B6011KR7005380001

000000388663

0002340000002335000000000030310

$

awk --re-interval '{ sub(/KR7[0-9]{9}/, "###123456789"); print }'

\contdata.txtB6011###1234567890000003886390002340000002335000000000030310B6012###1234567890000000082690003844000003843000000000000140B6011###1234567890000001237900014410000014400000000000007510B6011###1234567890000001238240014410000014400000000000007270

B6012###1234567890000000126490003837000003836000000000000280

B6011###

1234567890000003886630002340000002335000000000030310Slide38

Practice : function : gensubgensub(regex, replace, how [,target var.])

gawk를 사용한다면 gensub는 매우 유용하다.$ awk '{ a=gensub(/([0-9]+)/, "(\\1)", "g")

; print a}' /

etc/passwd

...

생략

...

sunyzero:x:(500):(500):SY Kim:/home/sunyzero:/bin/bash

$

awk

'{ a=gensub(/([0-9]+)/, "(\\1)", "1"); print a}' /etc/passwd...생략...

sunyzero:x:(500

):500:SY

Kim:/home/sunyzero:/

bin/bash

$

awk

'{ a=

gensub(/([0-9]+)/, "(\\1)",

"2")

;

print a}' /etc/passwd

...

생략

...

sunyzero:x:500:(500):

SY Kim:/home/sunyzero:/bin/bash

* how : g (global) , index (replace the n-th field)Slide39

Practice : function : gensub (con't)substitution function - backreference

를 지원하는 gensub$ cat contdata.txtB6011KR70053800010000003886390002340000002335000000000030310B6012KR70357600080000000082690003844000003843000000000000140

B6011KR70059300030000001237900014410000014400000000000007510

B6011KR70059300030000001238240014410000014400000000000007270

B6012KR70357600080000000126490003837000003836000000000000280

B6011KR7005380001

000000388663

0002340000002335000000000030310

$

awk

--re-interval '{ a=gensub(/KR7([0-9]{9})/, "###\\1", "g"); print a}' \contdata.txtB6011###005380001

0000003886390002340000002335000000000030310

B6012

###035760008

0000000082690003844000003843000000000000140

B6011

###005930003

0000001237900014410000014400000000000007510

B6011

###005930003

0000001238240014410000014400000000000007270

B6012

###035760008

0000000126490003837000003836000000000000280

B6011

###005380001

0000003886630002340000002335000000000030310

* gsub, sub

backreference

를 지원하지 못한다

.Slide40

Practice : gen. source codetest_posixopt.awk

BEGIN { cnt = 0 }# get posix options from file.{ elem[cnt++] = $1; }# end; print them; generate C source code.END {

for (i=0; i<=cnt; i++)

{

if (i == 0) {

print "#include <unistd.h>\n#include <stdio.h>\nint main()\n{\n"

} else if (i == cnt) {

print "\treturn 0;\n}"

} else {

printf("#if %s > 0L\n\tprintf(\"[O] %s\\n\");\n", elem[i], elem[i]);

printf("#else\n\tprintf(\"[X] %s\\n\");\n", elem[i], elem[i]); printf("#endif\n"); } }}Slide41

Practice : gen. source code (con't)test_posixopt.txt (

posixoptions manpage 참조)_POSIX_ADVISORY_INFO_POSIX_ASYNCHRONOUS_IO_POSIX_BARRIERS_POSIX_CLOCK_SELECTION

_

POSIX_CPUTIME

...

생략

...Slide42

Practice : gen. source code (con't)Makefile

# MakefileAWK = awkOUT = test_posixoptall: $(OUT).SUFFIXES:

.PRECIOUS: .o

%.c: %.awk

$(AWK) -f $< $*.txt | tee $@

%: %.o

$(CC) $< $(LOADLIBES) $(LDLIBS) -o $@

%.o: %.c

$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o

$@

clean: rm -f *.o core core.* $(OUT)Slide43

shell variable-v

varname="$shell_var"$ msg="Hello unixer"$

var_r

="

unix

"

$

var_s

="

linux

"$ echo $msg | awk '{gsub($var_r, $var_s);print}'

$ echo

$msg | awk

-v

r1="$var_r"

-v

s1="$var_s"

'{

gsub(r1, s1)

;

print

}'