2008. 10. 14.

AWK

AWK
awk는 직접 사용자로부터 입력을 받거나 아니면 지정한 파일을 가공하여 표준 출력한다
표준 출력을 리다이렉션할 수 있다
사용법
awk [옵션] '스크립트' [-v 변수=값] [파일(들)]
awk [옵션] -f 스크립트 파일 [-v 변수=값] [파일(들)]
cf) 편집 스크립트 파일의 사용법
ed : ed -s(script) sourcefile < scriptfile
sed : sed -f(file) scriptfile sourcefile > outputfile
awk : awk -f(file) scriptfile sourcefile > outputfile
옵션
-Fc : field separator 지정
c는 필드 사이를 구분하는 구분자이다

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

시스템 변수 FS를 지정하는 것과 같은 효과를 지닌다
-v 변수 = 값
스크립트를 실행하기 전에 미리 변수를 지정하여 준다
-f 스크립트 파일
스크립트를 파일에서 가져온다
-f 옵션을 여러번 사용하여 여러개의 스크립트 파일을 동시에 불러와 지정한 파일에 적용할 수 있다
스크립트
패턴 { 동작 }
커맨드 라인에서는 패턴, 동작 전체를 단일 따옴표로 묶는다
패턴만 있는 경우 : 패턴과 일치하는 레코드(라인)를 화면에 출력한다
동작만 있는 경우 : 모든 레코드(라인)가 동작의 대상이 된다
패턴
/정규표현식/
sed가 지원하지 않는 +, ?, |, ( ) 등의 메타문자도 지원한다 또한
^, $를 각 필드의 처음과 끝을 의미하도록 사용할 수도 있다
비교연산
숫자 기준, 알파벳 기준 모두 사용 가능하다
패턴 매칭 연산
~ : 일치하는 부분을 나타낸다
!~ : 일치하지 않는 부분을 나타낸다
BEGIN
첫 번째 레코드가 읽혀지기 전에 어떤 동작을 정의하여 사용하고 싶을 때 사용한다
END
마지막 레코드가 모두 읽혀진 후 어떤 동작을 정의하여 실행하고 싶을 때 사용한다
동작
동작은 모두 { }로 둘러싸야 한다
예제
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
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 명령어
문자열 연산
gsub(reg,s)
입력 문자열의 전반에 걸쳐 정규표현식 r을 문자열 s로 대치한다
gsub(reg,s1,s2)
문자열 s2에서 정규표현식 r을 s1으로 대치한다
index(s1,s2)
s1에서 s2의 위치를 넘겨준다 만약 없다면 0을 넘겨준다
length(arg)
인자의 길이를 넘겨준다
match(s,r)
문자열 s에서 정규표현식 r과 매칭되는 부분의 위치를 넘겨준다
split(string,array[,seperator])
구분자를 기준으로(지정하지 않으면 공백 기준)해서 지정한 문자열을 배열로 만든다 배열[1], 배열[2], .......
sub(r,s), sub(r,s1,s2)
gsub과 동일하다
단지 정규표현식과 일치하는 문자열이 여러개라도 처음 문자열만 대치된다
substr(s,m)
문자열 s에서 m번째 위치에서 끝까지의 문자를 리턴한다
substr(s,m,n)
문자열 s에서 m번째 위치에서 n번째까지의 문자를 리턴한다
tolower(str)
toupper(str)
수치 연산
atan2(x,y)
y/x의 arctangent값을 라디안 단위로 넘겨준다
cos(x)
exp(arg)
int(arg)
log(arg)
rand()
0과 1사이의 난수를 발생한다
sin(x)
sqrt(arg)
srand(expr)
인자를 가지고 난수를 발생한다
인자가 주어지지 않으면 시간을 가지고 난수를 발생한다
입출력/프로세스
close(filename)
지정한 파일을 닫는다
close(cmd)
지정한 명령어 파이프를 닫는다
delete array[element]
지정한 배열 요소를 지운다
getline()
다음 레코드를 읽어 들인다
getline[variable] [< "filename"]
파일에서 읽어들인다
next
다음 레코드(라인)을 입력받는다
getline()과 유사하지만 /패턴/동작을 새롭게 시작한다
getline()은 다음 라인을 읽기만 한다
print [args] [> "filename"]
인자를 출력한다
printf "format" [,expressions] [> "filename"]
형식에 맞춰 출력한다
sprintf (format [,expressions])
printf와 마찬가지로 사용하는데 값을 리턴하기만 하고 출력은 하지 않는다
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 '
지정한 파일의 짝수번째의 라인만을 출력해 준다

댓글 없음: