GNU Awk 사용자 가이드/패턴, 동작 그리고 변수
Variable의 개념
[+/-]변수란 data를 비롯하여 프로그램이 처리하는 값의 이름을 가리키는 말입니다. 예를 들어 아래와 같은 자료가 있다고 합시다.
키 | 몸무게 | 시력 |
---|---|---|
180 | 68 | 1.2 |
175 | 60 | 0.4 |
168 | 55 | 2.0 |
이 때 키, 몸무게, 시력과 같이 data를 분류하고 설명하는 이름들을 변수라고 할 수 있습니다. 만약 각각의 항목에 대하여 평균을 구한다고 하면 '평균'이란 요소 역시 변수의 하나가 됩니다.
awk에서는 변수를 크게 두 종류로 나눌 수 있습니다. 하나는 사용자가 임의로 자유롭게 만들 수 있는 사용자 정의 변수입니다. 프로그램의 목적에 따라서 사용자가 마음에 들어하는 이름으로 변수를 만들 수 있습니다. 다른 하나는 내장변수(Built-In Variable)란 것으로, awk에서 이미 만들어놓은 변수들입니다. 이 변수들은 각각 특정한 성질과 의미들을 갖고 있습니다. 내장변수들에 사용된 이름들은 사용자가 임의로 바꿀 수 없고 같은 이름으로 사용자 변수를 만드는 것도 불가능합니다.
Built-In Variable
[+/-]대부분의 awk 변수들은 사용자의 목적에 따라 이용이 가능합니다. 사용자의 프로그램이 그것들에 값을 바꾸기 전까지 변수들은 바뀌지 않으며 프로그램이 변수들을 사용하지 않는 한 그것들은 어떠한 영향도 미치지 않습니다. 하지만 awk의 일부 변수들은 특별하면서 내장된 의미를 갖고 있습니다. 내장변수는 크게 두 부류로 나눌 수 있는데 하나는 awk가 자동적으로 사용함으로써 사용자가 awk에게 어떤 일들을 하라고 명령이 가능하게 하는 변수들입니다. 나머지는 awk에 의해 자동적으로 설정됨으로써 awk의 내부 작업으로부터의 정보들을 사용자의 프로그램에 옮겨주는 기능을 합니다.
이 문서에서는 gawk의 주요 내장변수들을 사용목적에 따라 구분하고 설명하고자 합니다.
프로그램을 통제하는 내장변수
[+/-]아래의 것들은 사용자가 값을 바꿈으로써 awk 프로그램의 특정 데이터 처리방식을 조정할 수 있는 내장변수들입니다. gawk에만 해당하는 변수들은 # 표시하였습니다.
변수명 | 설명 |
---|---|
CONVFMT | 이 변수는 숫자를 문자열로 바꿔줍니다. 기본값은 "%.6g" |
FIELDWIDTHS # | input을 field의 길이로 나눌 때 사용. FS보다 우선순위가 앞선다 |
FS | Input에 대한 필드 구분자. Field Seperator의 약자. 사용자는 FS =" "에서 " "안에 기호를 넣음으로써 필드 구분자를 정의할 수 있다 |
OFMT # | 이 변수는 숫자를 문자열로 바꿔줍니다. CONVFMT이전에 사용되던 변수 |
OFS # | output에 대한 필드 구분자. 사용법은 FS와 동일 |
ORS # | output에 대한 레코드 구분자. |
RS # | Input에 대한 레코드 구분자 |
SUBSEP | subscript의 seperator |
TEXTDOMAIN # | awk 수준에서 프로그램을 국제화하기 위해 사용되는 변수. 이 변수는 기본적인 소스 텍스트에 표시된 문자로 텍스트 도메인을 설정합니다 |
정보를 전달하는 내장변수
[+/-]다음의 변수들은 사용자의 프로그램에 필요한 정보를 제공하기 위해 특정 성질의 값을 awk에서 자동적으로 설정한 것들입니다.
변수명 | 설명 |
---|---|
ARGV | 배열 안에 포함된 명령행 인자 |
ARGC | 존재하는 명령행 인자의 개수 표시 |
ARGIND | 현재 파일에서 처리되고 있는 ARGV에 대한 index |
ENVIRON | 다양한 환경값들을 연관있는 배열로 표시 |
EPRNO | getline으로 redirection하는 동안 에러가 발생했을 때 에러를 표시함 |
FILENAME | 현재 작업중인 파일의 이름 표시 |
FNR | 입력되는 파일이 여러 개인 경우 현재 처리중인 파일의 NF 표시 |
NF | 데이터의 필드 수를 표시 Number of Field |
NR | 데이터의 레코드 수를 표시 Number of Record |
PROCINFO# | 실행되고 있는 awk 프로그램에 대한 정보를 제공 |
RLENGTH | match 함수에 의해 매치된 하부문자열의 길이 표시 |
RSTART | match 함수에 의해 매치된 하부문자열의 시작지점 표시 |
RT# | RS에 의해 구별된 레코드 Input 텍스트를 표시 |
ARGV, ARGC 사용하기
[+/-]ARGV는 awk 프로그램에서 자주 쓰이는 내장변수입니다. ARGV는 사용자가 명령행에 입력한 인자를 인풋으로 받아 프로그램 내에서 처리할 수 있도록 도와주기 때문에 매우 유용합니다.
ARGV의 사용법을 익히기 위해 잠시 예를 살펴보겠습니다.
BEGIN {
print ARGV[1];
}
위와 같은 프로그램을 print.awk라고 저장하고 실행시키면 아래와 같은 결과가 나옵니다
$ gawk -f print.awk
이처럼 아무런 값이 출력되지 않는 이유는 내장변수 ARGV[1]에 해당하는 입력값을 넣지 않았기 때문입니다. 다음과 같이 해보겠습니다
$ gawk -f print.awk Hello
Hello
Hello라는 글자가 출력되었습니다. 이 경우에는 내장변수 ARGV[1]에 입력값 Hello를 넣어줬기 때문입니다. 이상에서 우리는 ARGV[1]가 명령행에서 명령어 다음 칸의 입력값을 가리키고 있음을 알 수 있습니다. 마찬가지로 ARGV[2]는 명령어로부터 다음다음칸의 입력값을 가리킬 것이라 생각할 수 있습니다. ARGV[1]과 ARGV[2]를 사용하는 프로그램을 만들어 보겠습니다.
BEGIN {
print ARGV[1], ARGV[2];
}
이 프로그램을 print2.awk라 저장하고 아래와 같이 실행시키면
$ gawk -f print2.awk Hello World
Hello World
가 나타납니다. 내장 변수 ARGV[i]는 이처럼 명령어를 기준으로 i번째에 해당하는 명령행 인자를 가리킵니다.
ARGC는 명령행 인자의 총 개수를 표시합니다. 이 변수를 ARGV와 같이 활용하면 조건문을 이용하여 루프 프로그램을 만드는 것이 가능합니다. 예제를 살펴보겠습니다.
BEGIN {
for (i = 0; i<ARGC; i++) {
print ARGV[i]
}
}
위와 같이 입력한 프로그램을 ARGC.awk 라 저장하고 다음과 같이 실행해봅시다.
$ gawk -f ARGC.awk Hello My World
Hello
My
Wolrd
ARGC를 이용한 루프 프로그램의 장점은 명령행 인자를 몇 개 입력했는지와 상관없이 일반화된 루프 처리가 가능하다는 것입니다.