linux

Total 136
Today 0
profile_image
ino
05-03-10 09:58 0개 2,971회
awk 까발려 보자 ㅋ
출저 : http://database.sarang.net/study/awk/awk.html

http://database.sarang.net/study/





AWK



1. awk는 직접 사용자로부터 입력을 받거나 아니면 지정한 파일을 가공하여 표준 출력한다

표준 출력을 리다이렉션할 수 있다

2. 사용법

* awk [옵션] '스크립트' [-v 변수=값] [파일(들)]

* awk [옵션] -f 스크립트 파일 [-v 변수=값] [파일(들)]

* cf) 편집 스크립트 파일의 사용법

o ed : ed -s(script) sourcefile < scriptfile

o sed : sed -f(file) scriptfile sourcefile > outputfile

o awk : awk -f(file) scriptfile sourcefile > outputfile

3. 옵션

* -Fc : field separator 지정

o c는 필드 사이를 구분하는 구분자이다

o 직접 지정하지 않으면 공백을 기준으로 한다

o 시스템 변수 FS를 지정하는 것과 같은 효과를 지닌다

* -v 변수 = 값

o 스크립트를 실행하기 전에 미리 변수를 지정하여 준다

* -f 스크립트 파일

o 스크립트를 파일에서 가져온다

o -f 옵션을 여러번 사용하여 여러개의 스크립트 파일을 동시에 불러와 지정한 파일에 적용할 수 있다

4. 스크립트

* 패턴 { 동작 }

커맨드 라인에서는 패턴, 동작 전체를 단일 따옴표로 묶는다

o 패턴만 있는 경우 : 패턴과 일치하는 레코드(라인)를 화면에 출력한다

o 동작만 있는 경우 : 모든 레코드(라인)가 동작의 대상이 된다

* 패턴

1. /정규표현식/

sed가 지원하지 않는 +, ?, |, ( ) 등의 메타문자도 지원한다 또한

^, $를 각 필드의 처음과 끝을 의미하도록 사용할 수도 있다

2. 비교연산

숫자 기준, 알파벳 기준 모두 사용 가능하다

3. 패턴 매칭 연산

~ : 일치하는 부분을 나타낸다

!~ : 일치하지 않는 부분을 나타낸다

4. BEGIN

첫 번째 레코드가 읽혀지기 전에 어떤 동작을 정의하여 사용하고 싶을 때 사용한다

5. END

마지막 레코드가 모두 읽혀진 후 어떤 동작을 정의하여 실행하고 싶을 때 사용한다

* 동작

o 동작은 모두 { }로 둘러싸야 한다

o 예제

+ good이라는 문자열을 포함하는 모든 레코드를 출력할 때

/good/

+ 각 레코드의 첫 번째 필드를 출력할 때

{ print $1 }

+ good이라는 문자열을 포함하는 레코드의 첫 번째 필드를 출력할 때

/good/ { print $1 }

+ 두 개 이상의 필드를 가지는 레코드를 전부 출력할 때(비교연산)

NF > 2

+ 한 라인(\n)을 필드로, 빈 라인("")을 레코드로 구분할 때

BEGIN { FS = "\n" ; RS = ""}

+ 첫 번째 필드가 good와 일치하는 레코드에 대해 세 번째 필드를 먼저 출력하고 두 번째 필드를 나중에 출력하고 싶을 때

$1 ~ /good/ { print $3 , $2 }

+ good이라는 문자열이 몇 개나 들어가 있는지 계산하여 마지막 부분에서 출력하고 싶을 때

/good/ { ++x }

END { print x }

+ 두 번째 필드를 모두 합하고 마지막 부분에서 두 번째 필드의 총합계를 출력하고 싶을 때

{ total += $2 }

END { print "Total of $2: " , total }

+ 레코드의 길이가 20자 이하인 것을 출력하고 싶을 때

length($0) < 20

+ 네 개의 필드를 가지며 good이라는 단어로 시작하는 모든 레코드를 출력하고 싶을 때

NF == 4 && /^good/

+ 빈줄을 제외한 모든 줄을 화면에 출력한다

NF > 0

5. awk 시스템 변수



FILENAME





현재 파일명





$0





입력 레코드



FS





입력 필드 구분

디폴트 : 공백





$n





입력 레코드의 N번째 필드



NF





현재 레코드 필드 갯수





ARGC





커맨드 라인의 인자 갯수



NR





현재 레코드 번호





ARGV





커맨드 라인 인자를 포함하는 배열



OFMT





숫자에 대한 출력 포맷

디폴트 : %.6g





ENVIRON





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



OFS





출력 필드 구분

디폴트 : 빈줄





FNR





NR과 동일

단지 현재 파일에 적용된다는 점이 다름



ORS





출력 레코드 구분

디폴트 : newline





RSTART





지정한 매칭 연산을 만족하는 문자열의 맨 앞부분



RS





입력 레코드 구분

디폴트 : newline





RLENGTH





지정한 매칭 연산을 만족하는 문자열의 길이



awk 연산자

#







산술 : =, +=, -=, *=, /=, %=





조건 : ? :





논리 : ||, &&, !





패턴 : ~, !~



비교 : <, <=, >, >=, !=,==





증감 : ++, --





필드참조 : $









제어문(C의 제어문과 같다)

#



* break

* continue

* do {실행} while (조건)

* exit

* for (관계형 배열의 요소) {실행}

펄의 foreach와 같다

* if (조건) {실행} else {실행}

* return

* while







# awk 명령어





* 문자열 연산

o gsub(reg,s)

입력 문자열의 전반에 걸쳐 정규표현식 r을 문자열 s로 대치한다

o gsub(reg,s1,s2)

문자열 s2에서 정규표현식 r을 s1으로 대치한다

o index(s1,s2)

s1에서 s2의 위치를 넘겨준다 만약 없다면 0을 넘겨준다

o length(arg)

인자의 길이를 넘겨준다

o match(s,r)

문자열 s에서 정규표현식 r과 매칭되는 부분의 위치를 넘겨준다

o split(string,array[,seperator])

구분자를 기준으로(지정하지 않으면 공백 기준)해서 지정한 문자열을 배열로 만든다 배열[1], 배열[2], .......

o sub(r,s), sub(r,s1,s2)

gsub과 동일하다

단지 정규표현식과 일치하는 문자열이 여러개라도 처음 문자열만 대치된다

o substr(s,m)

문자열 s에서 m번째 위치에서 끝까지의 문자를 리턴한다

o substr(s,m,n)

문자열 s에서 m번째 위치에서 n번째까지의 문자를 리턴한다

o tolower(str)

o toupper(str)

* 수치 연산

o atan2(x,y)

y/x의 arctangent값을 라디안 단위로 넘겨준다

o cos(x)

o exp(arg)

o int(arg)

o log(arg)

o rand()

0과 1사이의 난수를 발생한다

o sin(x)

o sqrt(arg)

o srand(expr)

인자를 가지고 난수를 발생한다

인자가 주어지지 않으면 시간을 가지고 난수를 발생한다

* 입출력/프로세스

o close(filename)

지정한 파일을 닫는다

o close(cmd)

지정한 명령어 파이프를 닫는다

o delete array[element]

지정한 배열 요소를 지운다

o getline()

다음 레코드를 읽어 들인다

o getline[variable] [< "filename"]

파일에서 읽어들인다

o next

다음 레코드(라인)을 입력받는다

getline()과 유사하지만 /패턴/동작을 새롭게 시작한다

getline()은 다음 라인을 읽기만 한다

o print [args] [> "filename"]

인자를 출력한다

o printf "format" [,expressions] [> "filename"]

형식에 맞춰 출력한다

o sprintf (format [,expressions])

printf와 마찬가지로 사용하는데 값을 리턴하기만 하고 출력은 하지 않는다

o system(command)

시스템 내부 명령어를 실행한다







# 간단한 예





* awk ' BEGIN { for (i = 1;i<=7,i++) print int(101*rand()) }'

화면에 1이상 100이하의 난수 일곱 개를 출력한다

* ls -l file1 file2 file3 | awk ' { x += $5 } ; END { print "Total bytes : " x } '

파일들의 크기를 모두 합하여 총 바이트 수를 표시한다

* awk ' END { print NR } ' filename

지정한 파일의 라인이 몇 개인지를 표시한다

* awk ' NR % 2 == 0 '

지정한 파일의 짝수번째의 라인만을 출력해 준다







참고서적 : sed & awk, Dale Daugherty, O'reilly

댓글목록

등록된 댓글이 없습니다.