개요
AWK(오크;Aho Weinberger Kernighan)는 유닉스에서 처음 개발된 일반 스크립트 언어이다. AWK의 기본 기능은 텍스트 형태로 되어있는 입력 데이터를 행과 단어 별로 처리해 출력하는 것이다. AWK라는 이름은 이 스크립트 언어를 만든 앨프리드 에이호, 피터 와인버거, 브라이언 커니핸 세 명의 성의 앞글자를 따서 붙여졌다.
예) 다음 명령어는 page fault의 평균 시간을 구한다.
sudo perf ftrace -T "do_page_fault" ./test_huge_page > pref.out awk '{total += $2; count++ } END {print total/count; print total; print count }' perf.out
awk 프로그램의 구조
awk는 크게 명령 파일과 주 입력 파일 두 가지 데이터를 받아 실행된다. 명령 파일은 awk가 입력 데이터를 어떤 규칙에 따라 처리할지를 지시한다. 명령 파일은 커맨드 라인을 통해 직접 입력될 수도 있으며 미리 작성된 파일일 수도 있다. 입력파일은 보통 특정한 형식에 따라 작성된 텍스트 파일이다. 입력 역시 실제 파일 형태로 입력될 수도 있고, 표준입력을 통해 입력될 수도 있다. 명령 파일에 해당하는 awk 프로그램은 다음 형태의 명령이 여러 줄 이어진 구조로 되어 있다.
/패턴/ { 동작 }
여기서 패턴은 정규 표현식이며, 동작은 실행명령이다. awk는 입력파일을 처음부터 한 줄씩 입력받아 주어진 패턴과 일치하는 줄을 찾으면 그 줄에서 동작에 해당하는 명령을 실행한다. 패턴-동작의 형태 이외에도 다음과 같은 명령도 awk 프로그램에서 가능하다.
BEGIN { 동작 } # 입력을 읽기 전에 주어진 '동작'을 먼저 실행한다.
END { 액션 } # 위와 비슷하다. 주입력을 모두 훑고 마지막에 주어진 '액션'을 실행한다.
/패턴/ # '패턴'에 일치하는 줄을 출력한다.
{ 동작 } # 매 줄을 읽을 때마다 '동작'을 실행한다.
각 형태의 명령은 명령 파일에서 여러번 올 수 있다. 각각은 명령 파일에 쓰여진 순서에 따라 실행된다. 즉, "BEGIN
" 문이 두번 주어져 있으면 앞에 있는 "BEGIN
" 문이 실행된 후에 다음에 오는 "BEGIN
" 문이 실행된다. 그러나 "BEGIN
" 문은 다른 명령들 사이에 있더라도 다른 명령들이 실행되기 전에 실행된다. 이는 "END
" 문에 대해서도 마찬가지이다.
Awk 명령어
awk 명령어는 위에서 동작이라고 쓰인 위치에 쓰여 실제 동작을 지시하는 명령어이다. awk 명령어는 함수호출, 변수값 지정, 산술계산과 이들을 조합한 어떤 것이 될 수 있다. awk는 다양한 함수들을 기본적으로 지원하고 변종에 따라 다른 기타 기능들이 들어갈 수 있다. 어떤 것은 동적 링크 라이브러리를 지원하기도 한다.
간결성을 위해서 아래 예에서 중괄호({ }
)는 생략했다.
print
명령어
print
는 텍스트를 출력한다. 이 명령어만 홀로 쓰면,
print
현재 줄의 내용을 출력한다. awk에서 한 줄은 자동적으로 여러 개의 필드[1]로 구분지어진다. 필드는 print 명령에서 다음과 같이 따로따로 출력될 수 있다.
print $1 # 현재 줄의 첫 번째 필드를 출력한다.
print $1, $3 # 첫 번째와 세 번째 필드를 출력하며,
# 둘 사이에는 디폴트로 빈칸(스페이스) 하나로 주어지는 OFS(출력 필드 구분자, output field seperator)가 들어간다.
X(X는 숫자)번째 필드는 $X
로 표시되며, 특별히 $0
은 줄 전체를 지정한다. 실제로 "print
" 과 "print $0
" 는 똑같은 결과를 가져온다.
print는 계산의 결과나 함수호출의 결과값을 뿌릴 수도 있다:
print 3+2
print foobar(3)
print foobar(variable)
print sin(3-2)
물론 출력은 다음과 같이 하여 표준출력이 아닌 다른 파일로 쓸 수도 있다.
print "expression" > "file name"
변수 등등
변수 이름은 알파벳 대소문자와 숫자[2]로 표현되는 문자들의 조합으로 만들 수 있다. 단 awk의 예약어는 변수가 될 수 없다. + - * /
는 각각 덧셈, 뺄셈, 곱셈, 나눗셈을 나타낸다. 문자열을 합치고 싶을 때에는 단순히 변수나 고정 문자열을 붙여 쓰기만 하면 된다. 고정 문자열은 겹따옴표로 구분되며, 세미콜론으로 문(statement)의 끝을 표시할 필요는 없다. 주석문은 첫머리에 #를 달아 표시한다.
사용자 정의 함수
C와 비슷하게, 함수 선언은 함수 이름과 함수의 인자들로 이루어진다.
function add_three (number ,temp) {
temp = number + 3
return temp
}
이 함수는 다음과 같이 쓰일 수 있다.
print add_three(36) # prints '''39'''
함수는 함수 내부에서만 쓰이는 지역변수를 가질 수 있다. 이 지역변수는 인자 목록 끝에 포함된다. 그러나 함수를 부를 때는 이 변수 자리에 아무것도 쓰지 않는다. 이들을 구분하기 위해 함수가 넘겨받는 인자와 지역변수 사이에 빈칸을 좀 집어넣어 구분하는 것이 암묵적 약속이다.