1. awk의 기본 개념
1) awk란?
; awk란 이름은 이 유틸리티를 작성한 A.V.Aho, P.J. Weinberger, B. Kernigham의
머리글자를 따온 것
① awk는 일종의 프로그래밍 언어지만 일반적인 언어라기 보다는 주로 패턴의 검색과 조작을 주목적으로 만들어진
것이다.
② 파일의 각 라인에서 필드(field)를 인식할 수 있는 패턴 매칭 기능을 가지고 이들 필드를 자유자재로 조작 가능한 유틸리티를
작성하고자 만든 것이다.
2) awk의 응용분야
데이터 프로세싱, 리포트 작성, 간단한 데이터베이스 구축,
등
3) awk를 이용한 작업
① 프로그래머가 자신이 작성한 프로그램의 입력 화일이 특정한 형식에 들어 맞게 이루어져 있는지
검사.
② 출력화일을 처리하여 리포트를 만들어 냄.
③ 다른 프로그램의 입력 형식에 맞게 변환하는 작업에
이용.
2. awk 프로그램의 구조 및 실행
(1) awk 프로그램의 구조
1) awk ' pattern {action}
pattern {action}
.
.
.
' filenames
<-----------------입력화일(예제 : students)
2) awk -f
parttern-action-file filenames <----- 입력화일
awk실행 action을 가진 프로그램 file
(2) awk의 pattern
패 턴 |
내 용 |
BEGIN |
입력화일을 읽어들이기 전에 옆에 제시되는 문자을 실행시키도록 한다. |
END |
awk가 모든 입력을 처리한 후, 옆에 제시되는 문장을 실행시키도록 한다. |
expression |
식을 평가한 후 이 식이 참, 즉 non-zero이거나 non-null인 경우 문장을 실행한다. |
/re/ |
정규식과 일치하는 문자열을 포함하고 있는 라인에서 문장을 실행한다. |
compound-pattern |
복합패턴이라는 것으로 &&(and), ||(or) , !(not) 그리고 괄호에 의해 연결시킨 것이다.
expression의 경우와 마찬가지로 복합 패턴도 참인 경우의 문장을 실행시킨다. |
pattern1, pattern2 |
이러한 패턴을 범위 패턴이라한다. 현재 처리되고 있는 라인이 pattern1과 일치되고, 다음에 따라오 는 라인 중 임의의 라인이
pattern2와 일치할 때, 범위 패턴은 두 라인 사이의 각 라인과
일치한다. |
(3) awk의 연산자
연 산 자 |
내용 |
= += -= *= /= %= |
배정(assignment)연산자 |
+ - * / % ++ -- |
산술 연산자 |
|| && ! |
논리 연산자(|| = OR, && = AND, ! = NOT) |
> >= < <= == != |
비교 연산자 |
v ~p |
변수 V가 패턴 P에 부합되면 참 |
v !~p |
변수 V가 패턴 P에 부합되지 않으면 참 |
(4) 액션(Actions)
액션은
문장(statements)으로 이루어져 있다. 액션은 간단하게 상수 하나로 이루어질 수도 있고, 개행 문자나 세미콜론(;)에 의해 분리된 몇
개의 문장의 연속으로 구성될 수도 있다.
① expressions
② print expression-list
③ printf(format,
expression-list)
④ if (expression) statement
⑤ if (expression) statement
else statement
⑥ while (expression) statement
⑦ for (expression;
expression; expression) statement
⑧ for (variable in array) statement
⑨ do
statement while (expression)
⑩ break
⑪ continue
⑫ next
⑬ exit
⑭
exit expression
⑮ {statement}
(5) awk에서 미리 정의된 몇가지 변수들
변 수 |
내 용 |
FILENAME |
현재 처리되고 있는 입력 파일의 이름 |
FS |
입력 필드 분리문자 |
NR |
현재 레코드(행)의 번호 |
NF |
현재 레코드(행)의 필드의 갯수 |
OFS |
출력되는 필드의 분리문자 |
|
3. awk의 기본예제
(1) 예제 입력 파일 소개
① 입력화일의 이름은 students
② 이 파일의 각 라인은 3개의 필드로 구성(학생 성명, 학과명, 나이)
③ 각 필드는
공백에 의해서 분리(공백을 필드 분리자로 간주함.)
< awk는 각 라인에서 필드를 추출해 내는 데 필드 분리자(field
separator)를 사용, 필드 분리자는 보통 하나 이상의 공백 문자이다.>
1) 입력화일 예제 students
% cat students
John,P Physics 20
Rick,L Mechanical 21
Jack,T
electrical 23
Larry,M Chemical 22
Phil,R Electrical 21
Mike,T
mechanical 22
Paul,R Chemical 23
John,T Chemical 23
Tony,N Chemical
22
James,R Electrical 21
예 1) 식(expression)에 맞는 field 프린트하기
% awk '$3 > 22 {print $1}'
students
Jack,T
Paul,R
John,T
예 2) if 문을 사용하여 조건에 맞는
line 분리하기(각 파일에 저장)
step 1 : if문을 사용하는 프로그램을 awkprog1이라는 파일로 만든다.
% cat awkprog1
{ if ($1 ~ /^J/) printf "%s\n", $0 > "Jfile"
if
($1 ~ /^P/) printf "%s\n", $0 > "Pfile"}
step 2 : students 입력화일에
awkpog1 프로그램 화일을 적용한다.
% awk -f awkprog1 students
step 3 : 결과 보기
% cat Jfile
John,P Physics 20
Jack,T electrical 23
John,T Chemical
23
James,R Electrical 21
% cat Pfile
Phil,R Electrical 21
Paul,R
Chemical 23
예 3) 평균값 구하기
<프로그램 awkprog2, awkprog3>
% cat awkprog2
{sum +=
$3}
END {printf "The average of the ages is %.2f\n", sum/NR}
% cat
awkprog3
{sum += $3
++no}
END {printf "The average of the ages is
%.2f\n", sum/no}
<결 과>
% awk -f awkprog3 students
The average
of the ages is 21.80
예 4) while 과 do문을 이용하여 평균값 구하기
<프로그램 awkprog4>
% cat awkprog4
{if (NF > 0) {
sum =
0
n = 1
while (n <= NF) {
sum = sum + $n
n = n+1
}
printf
"Average is %d\n", sum/NF
}
else
print}
<예 제>
% awk -f
awkprog4 test
Average is 17
Average is 3
Average is 25
Average is
0
---------------------------------------------------------------------------
[awk 기본 문법]
awk [-f prog-file] [-F c]
[ 'pattern {action}' ] [filename]
-f prog-file
awk의 실행 Action을
가진 프로그램 파일 지정
-F c
필드 구별자(FS: Field
Separator) 지정
'pattern {action}'
awk
program의 command 문장은 single quotes(' ') 또는 double quotes(" ")로
둘러싸여 있습니다.
Input의 각 라인(Line)이 원하는 pattern과
일치하면, action 부분이 실행됩니다.
action 없이 pattern만 있는 경우, 원하는
pattern을 찾으면 각 Input 라인을 그대로
출력합니다.
pattern
없이 action만 있는 경우, Input의 각 라인에 대해 action을 실행합니다.
action 부분은
항상 중괄호({})로 둘러싸여 있습니다.
여러 action을 실행 시, action 사이를 세미콜론(;)이나
new-line 문자로 구분할 수
있습니다.
패턴유형 설 명
BEGIN
입력파일을 읽어 들이기 전에, BEGIN 옆에 제시되는 { } 안의
Action을 실행시킵니다.
END 모든 입력을 처리한 후,
END 옆에 제시되는 { } 안의 Action을
실행시킵니다.
expression 식을 평가한 후, 이 식이 참이면 즉
non-zero 이거나 non-null 인 경우,
뒤의 Action을 실행시킵니다.
/re/ 정규식과 일치하는 문자열을 포함하고
있는 라인에서 Action을
실행시킵니다.
compound-
pattern 복합 패턴이라는 것으로 여러 개의
expression을 괄호와 &&(and),
||(or) , !(not) 로 연결시켜 그 결과가 참인 경우
Action을
실행시킵니다.
pattern1,
pattern2 이러한 패턴을 범위 패턴이라고 합니다. 현재 처리되고
있는 라인이
pattern1과 일치되고, 다음에 따라오는 라인 중 임의의 라인이
pattern2와 일치할 때, 범위 패턴은 두 라인
사이의 각 라인과
일치합니다.
filename
awk 프로그램에 입력될 입력 파일 지정
awk에는 awk가 내부적으로 가지는 변수들이 있습니다. 이 변수들을 사용하여, 필드
및
레코드의 구분을 좀 더 다양하게 할 수 있으며, 좀 더 유연한(flexible)프로그램을 짤 수가
있습니다.
아래 표는 각 내부 변수들에 대해서 설명하고 있습니다.
내부
변수 설 명
FILENAME 현재 처리하고 있는 file의 이름
FS Field Separator- 필드
구분자
RS Record Separator - 레코드 구분자
NF Number of Fields - 현재
레코드의 필드 수
NR Number of Records - 현재 레코드의 번호
$1 입력되는 Record의 첫 번째
필드
$n 입력되는 Record의 n 번째 필드
OFS Output Fields Separator - 출력시의
FS.
이 값을 변경하게 되면, 출력시의 FS가 바뀌게 됩니다.
ORS Output Records Separator - 출력시의
RS.
이 값을 변경하게 되면, 출력시의 RS가 바뀌게 됩니다.
내부
변수 사용 예
test.txt 파일을 확인한 결과가 다음는 같았습니다.
$ cat test.txt
AA aaa bbb ccc ddd
BB bbb ccc ddd
eee
CC ccc ddd eee fff
DD ddd eee fff ggg
이 파일의 필드수를 구하는 명령은 다음과 같습니다.
$
awk '{print NF}' test.txt
5
5
5
5
4개의 각 레코드가 가지는 필드
수가 5개씩이므로 화면에는 5가 4번 찍힙니다.
hello.txt 파일의 내용은 다음과 같습니다.
$ cat Hello.txt
Hello, World!!
Be The Reds!!
여기서 awk 명령을 이용하여 Hello 필드를 포함하고 있는 모든 레코드를 출력하기
위한
명령은 다음과 같습니다.
$ awk '/Hello/' Hello.txt
Hello, World!!
action 부분이 없을 때는 Hello 필드를 포함하고 있는 모든 레코드가 출력됩니다.
awk의 Output을 다른 파일로 보내기
awk의 출력
action을 다른 파일로 보내기 위해서는 '>'나 '>>'를 사용하면 됩니다.
현재 디렉토리와 해당 파일의 내용을 확인한 결과는 다음과 같습니다.
$ ls
Hello.txt
$ cat Hello.txt
Hello, World!!
Be The Reds!!
첫 번째 필드는 file1.txt 파일로, 두 번째 필드는 모니터로 출력하려면
다음과 같이
명령을 실행합니다.
$ awk '/Hello/ {print $1 > "file1.txt";
print $2}' Hello.txt
World!!
file1.txt 파일이 없으므로 신규
생성하여 데이터를 입력합니다.
이를 확인한 결과는 다음과 같습니다.
$ ls
Hello.txt
file1.txt
$ cat file1.txt
Hello,
일반적인 특수 문자
awk의
검색 패턴을 만들 경우 slash(/)로 감싸서 표현하는데, slash 사이에는 다음과 같은
특수 문자를 사용할 수 있습니다.
특수 문자 설명
| Bar(|)의 왼쪽과 오른쪽의 논리적 OR 연산
+ 선행하는 패턴의 하나
또는 그 이상의 반복
? 선행하는 패턴이 없거나 또는 한번만 나타남을 의미
* 선행하는 패턴의 임의의 횟수의 반복
[]
대괄호([]) 사이의 임의의 문자 하나
[a-z] 두 문자 사이의 임의의 문자 하나
^ 라인의 처음을 의미
$ 라인의
마지막을 의미
. Period 위치의 문자 하나
다음 문자의 특수한 의미를 없앰
() 패턴을 그룹화 함
$ cat Hello.txt
Hello, World!!
Be
The Reds!!
다음의 명령은 위의 파일에서 Be로 시작되는 레코드를 검색하여
출력합니다.
$ awk '/^Be/' Hello.txt
Be The Reds!!
관계 연산자
awk의 패턴 표시에도
관계 연산자인 <, <=, ==, !=, >=, >를 사용할 수 있습니다.
관계 연산자
설명
A < B A가 B보다 작다.
A <= B A가 B보다 작거나 같다.
A == B A와 B가 같다.
A != B A와 B가 같지 않다.
A >= B A가 B보다 크거나 같다.
A > B A가 B보다 크다.
$ cat num.txt
1 10 100 1000
10000
10000 1000 100 10 1
다음의 사용예는 첫째 필드의 값이 둘째 필드의
값보다 큰 레코드를 출력하는
것입니다.
$ awk '$1 > $2' num.txt
awk의 제어문은 C의 제어문과 비슷하며 다음과 같이 사용할 수 있습니다.
if 문
if 문의 기본 문법
if(condition) Action
else Action
if 문의 사용 예
$
awk '{if($1 != "Hello,") print $0; else print "Wow!!"}' Hello.txt
Wow!!
Be
The Reds!!
첫째 필드가 "Hello,"이면 Wow!!를 출력하고, 아니면 해당
레코드를 출력합니다.
!!$0 은 해당 레코드 전체!!
while 문
while 문의 기본 문법
while(condition) Action
while
문의 사용 예
$ awk '{i=1; while(i<=2) {print
$(i); i++}}' Hello.txt
Hello,
World!!
Be
The
변수 i는 1의 정수값(i=1)으로 시작하고 계속 1씩 증가(i++) 합니다. i 값이 2보다 작거나
같을 동안
Action을 실행하는데, 출력될 필드도 변수 i 값에 맞추어 다르게 선정됩니다.
for 문
for 문의 기본 문법
for (initialize; final; increment) { Action }
for 문의 사용 예
$ awk
'{for(i=1;i<NF;i++) {print $(i)}}' Hello.txt
Hello,
Be
The
변수 i는 1의 정수값(i=1)으로
시작하여 계속 1씩 증가(i++) 합니다.
i 값이 레코드의 필드 수(NF)보다 작을 동안만 Action을 실행하는데, 출력될 필드도 변수
i 값에
맞추어 다르게 선정됩니다.
awk에는 print, printf 외에
다음과 같은 내장함수가 있습니다.
내장함수 설명
length(x) 문자 x의 길이 반환
awk '{print length($1); print $1}'
hello.txt
6
Hello,
2
Be
sqrt(x) x의 평방제곱근 값 반환
log(x) x의 Log 값
반환
exp(x) x의 Exponential 값 반환
int(x) x의 정수 값 반환
cos(x) x의 Cosine 값
반환
atan(x) x의 Arctangent 값 반환
rand(x) 0에서 1사이의 임의의 값 반환
sin(x)/td> x의 Sine 값 반환
sran(x) rand(x)의 새로운 Seed 값 반환
match(s, r) r번 발생하는 s의 위치를 돌려주거나 0을 반환
substr(s, m, n) s 문자열에서 m 위치에서
시작하여 n개의 문자를 반환
sub(r, t, s) s 문자열에 있는 첫 번째 r과 t를 치환
gsub(r, t, s)
sub()와 같으나 해당하는 모든 경우를 치환
split(s, array, sep) 문자열 s를 array[1]..array[n]으로
나눕니다.
sep이 지정되지 않으면 FS 값을 기본으로 합니다.
index(s1, s2) s1에서 s2 문자가 검색된 위치를
알려줍니다.
toupper(s) 문자 s를 대문자로 치환
tolower(s) 문자 s를 소문자로 치환
system(command) 유닉스 명령어 command를 실행하고 exit 상태를 반환