문서의 각 단락이 어느 리비전에서 마지막으로 수정되었는지 확인할 수 있습니다. 왼쪽의 정보 칩을 통해 작성자와 수정 시점을 파악하세요.

awk | |
개발자 | 앨프 에호, 피터 J. 와인버거, 브라이언 커니핸 |
발표일 | 1977년 |
최근 안정화 버전 | IEEE Std 1003.1-2008 (POSIX) / 2012년 |
운영 체제 | 크로스 플랫폼 |
라이선스 | 오픈 소스 |
상세 정보 | |
영향을 받은 언어 | C, SNOBOL, sed |
파일 확장자 | .awk |
패러다임 | 스크립트, 절차적, 데이터 중심 |
주요 구현체 | awk, nawk, mawk, gawk |
설계 목적 | 텍스트 처리, 데이터 추출, 보고서 생성 |
주요 특징 | 패턴-액션 모델, 내장 변수(FS, OFS, RS, ORS, NR, NF 등), 연관 배열, 정규 표현식 지원 |
표준 | POSIX, Single UNIX Specification |
사용 예시 | 로그 파일 분석, 데이터 형식 변환, 간단한 계산 및 보고서 작성 |

awk는 텍스트 처리와 데이터 추출 및 변환을 위한 강력한 프로그래밍 언어이자 명령줄 도구이다. 앨프 에호, 피터 J. 와인버거, 브라이언 커니핸에 의해 1977년에 개발되었으며, 그 이름은 개발자들의 성 이니셜에서 따왔다.
이 언어는 주로 구조화된 텍스트 데이터, 특히 공백이나 특정 구분자로 필드가 나뉜 레코드 형태의 데이터를 처리하는 데 최적화되어 있다. 기본 동작은 입력 데이터를 한 줄씩 읽어 미리 정의된 패턴과 비교한 후, 해당 패턴에 맞는 줄에 대해 지정된 액션을 실행하는 것이다.
awk는 크로스 플랫폼 환경에서 동작하며, 오픈 소스 라이선스를 가진다. 그 간결함과 효율성 덕분에 유닉스 및 리눅스 시스템에서 로그 분석, 데이터 정제, 간단한 보고서 생성 등 다양한 셸 스크립팅 작업에 필수적으로 활용되고 있다.
표준화 측면에서는 2012년에 발표된 IEEE Std 1003.1-2008(POSIX) 표준에 명세가 포함되어 있으며, 이는 현재의 안정화 기준으로 간주된다.

awk는 1977년 벨 연구소에서 개발된 텍스트 처리 프로그래밍 언어이다. 이 언어는 개발자 앨프 에호, 피터 J. 와인버거, 브라이언 커니핸의 성을 따서 이름 지어졌다. 당시 벨 연구소에서는 데이터 처리와 보고서 생성에 유용한 도구가 필요했고, 이에 따라 세 명의 개발자가 기존 언어인 C와 sed의 아이디어를 결합하여 awk를 창안했다.
awk는 초기 유닉스 시스템의 제7판에 포함되면서 본격적으로 보급되기 시작했다. 이 언어는 텍스트 파일의 각 줄을 레코드로, 공백으로 구분된 단어를 필드로 자동 인식하여 처리하는 독특한 방식을 채택했는데, 이는 데이터 추출과 변환 작업을 매우 간편하게 만들어 주었다. 이러한 특징으로 인해 awk는 시스템 관리와 로그 분석 분야에서 빠르게 필수 도구로 자리잡았다.
시간이 지나면서 awk의 기능과 성능에 대한 요구가 증가했고, 이에 따라 여러 변종이 등장하기 시작했다. 1985년에는 원본 awk의 제한 사항을 개선한 nawk가 공개되었으며, 이후 gawk가 GNU 프로젝트의 일환으로 개발되어 가장 널리 사용되는 구현체가 되었다. awk는 1992년 POSIX 표준으로 채택되어 공식적인 유닉스 도구의 지위를 얻었고, 그 명세는 2012년에 개정된 IEEE Std 1003.1-2008에 포함되어 현재까지 유지되고 있다.
오늘날 awk는 수많은 리눅스 배포판과 유닉스 계열 시스템에 기본적으로 포함되어 있으며, 셸 스크립트와 결합하여 강력한 텍스트 처리 파이프라인을 구성하는 데 핵심적으로 사용되고 있다. 그 탄생 배경과 표준화 과정은 초기 유닉스 철학인 "한 가지 일을 잘 하는 도구"를 만들고 이를 조합한다는 정신을 잘 보여주는 사례이다.

awk 프로그램의 핵심 구조는 '패턴 { 액션 }' 형태로 이루어진다. 이 구조는 입력 데이터의 각 레코드(기본적으로 한 줄)를 순차적으로 읽으면서, 지정된 패턴과 일치하는 레코드에 대해서만 중괄호 안에 정의된 액션을 실행한다.
패턴은 생략될 수 있으며, 이 경우 액션은 모든 입력 레코드에 대해 실행된다. 패턴은 정규 표현식, 관계 연산을 이용한 조건식, 특수 패턴인 BEGIN과 END 등이 사용된다. BEGIN 패턴은 첫 번째 입력 레코드를 읽기 전에 한 번 실행되는 액션을 정의할 때 사용되며, 초기화 작업에 적합하다. 반대로 END 패턴은 모든 입력 레코드 처리가 끝난 후 마지막에 한 번 실행된다.
액션 부분은 중괄호로 둘러싸인 하나 이상의 명령문으로 구성된다. 이 명령문들은 변수 할당, 산술 연산, 문자열 조작, 제어 흐름 문(if, while, for 등), 출력문(print) 등을 포함할 수 있다. 액션 역시 생략될 수 있는데, 이 경우 기본 액션인 'print $0'(현재 전체 레코드 출력)이 수행된다.
이러한 패턴-액션 모델은 데이터를 선별적으로 처리하고 변환하는 데 매우 효율적이다. 예를 들어, 특정 필드 값이 조건을 만족하는 줄만 찾아서 출력하거나, 레코드를 읽는 동안 합계를 계산한 후 최종 결과만 END 블록에서 출력하는 등의 작업이 가능해진다.
awk 스크립트 내에서 자동으로 설정되거나 사용자가 활용할 수 있는 주요 내장 변수들이 존재한다. 이 변수들은 현재 처리 중인 레코드(행)와 필드(열)에 대한 정보, 명령줄 인자, 배열의 인덱스 순회 등 다양한 컨텍스트를 제공한다.
가장 기본적이고 자주 사용되는 내장 변수로는 FS, OFS, RS, ORS, NF, NR, FNR 등이 있다. FS는 입력 필드 구분자로, 기본값은 공백이다. OFS는 출력 시 필드 사이에 삽입되는 구분자다. RS는 입력 레코드 구분자(기본값은 개행 문자), ORS는 출력 레코드 구분자를 지정한다. NF는 현재 레코드의 필드 개수를, NR은 지금까지 처리한 총 레코드 번호를, FNR은 현재 파일 내에서의 레코드 번호를 나타낸다.
명령줄에서 전달된 인자는 ARGV 배열과 ARGC 변수로 접근할 수 있다. 또한, FILENAME 변수는 현재 처리 중인 입력 파일의 이름을 담고 있다. 사용자 정의 함수의 매개변수 개수를 확인하는 ARGC와는 별개로, 배열을 순회할 때 사용하는 for (index in array) 구문에서 index는 내부적으로 관리되는 변수 역할을 한다.
이러한 내장 변수들은 BEGIN 블록에서 초기값을 설정하거나, 패턴-액션 블록 내에서 값을 참조하거나 변경하여 데이터 처리의 흐름을 세밀하게 제어하는 데 활용된다. 예를 들어, NR==1 패턴으로 헤더 행을 처리하거나, NF 값을 통해 필드 개수가 일정하지 않은 레코드를 걸러낼 수 있다.
awk는 다양한 연산자와 내장 함수를 제공하여 텍스트 데이터를 효율적으로 처리하고 변환할 수 있다.
연산자에는 산술 연산자(+, -, *, /, %, ^), 대입 연산자(=, +=, -= 등), 비교 연산자(==, !=, <, >, <=, >=), 논리 연산자(&&, ||, !), 그리고 문자열 연결 연산자(공백)가 포함된다. 특히 패턴 매칭에 사용되는 ~(일치)와 !~(불일치) 연산자는 정규 표현식과 함께 강력한 텍스트 검색 기능을 제공한다. 삼항 조건 연산자 ? :도 지원되어 조건에 따른 값을 간결하게 할당할 수 있다.
내장 함수는 크게 산술 함수, 문자열 함수, 시간 함수, 입출력 함수 등으로 구분된다. 대표적인 문자열 함수로는 length()(문자열 길이), substr()(부분 문자열 추출), index()(문자열 위치 찾기), split()(문자열 분할), sub()와 gsub()(문자열 치환) 등이 있다. 산술 함수에는 int(), sqrt(), rand()(난수 생성), srand()(난수 시드 설정) 등이 포함된다. 또한 getline 함수는 표준 입력이나 파일에서 새로운 레코드를 읽어오는 데 사용된다.
사용자는 필요에 따라 자신만의 함수를 정의할 수도 있다. 함수 정의는 function 키워드로 시작하며, 매개변수를 받고 값을 반환할 수 있어 복잡한 로직을 모듈화하는 데 유용하다. 이러한 연산자와 함수들을 조합하면 데이터 필터링, 형식 변환, 요약 보고서 생성 등 다양한 텍스트 처리 작업을 awk 스크립트 하나로 수행할 수 있다.

awk는 본질적으로 텍스트 처리와 필터링을 위해 설계된 도구이다. 이는 구조화된 텍스트 데이터, 특히 필드와 레코드로 구성된 데이터를 처리하는 데 탁월하다. awk는 입력 데이터를 레코드(기본적으로 줄 단위)로 읽고, 각 레코드를 미리 정의된 필드 구분자(기본적으로 공백)에 따라 필드로 나누어 처리한다. 이 구조화된 접근 방식을 통해 사용자는 특정 필드에 쉽게 접근하고 조건에 따라 데이터를 걸러내거나 변형할 수 있다.
가장 기본적인 필터링은 패턴 매칭을 통해 이루어진다. awk는 입력 레코드를 읽을 때마다 사용자가 지정한 패턴과 비교한다. 패턴은 정규 표현식, 관계 연산, 특정 필드 값에 대한 조건 등이 될 수 있다. 패턴에 맞는 레코드만 선택되어 연결된 액션(명령)이 실행된다. 예를 들어, 특정 문자열을 포함하는 줄만 출력하거나, 세 번째 필드의 값이 기준치를 넘는 레코드만 추출하는 작업이 이에 해당한다.
데이터 추출과 변환은 awk의 핵심 기능 중 하나이다. 내장 변수인 NF(필드 수)와 NR(레코드 번호)를 활용하면 데이터의 구조와 위치를 파악하기 쉽다. 사용자는 $1, $2와 같은 필드 변수를 사용해 원하는 데이터를 직접 참조하거나 변경할 수 있다. 또한, printf 문을 이용해 필드의 순서를 재배열하거나 서식을 지정하여 출력할 수 있어, 원본 데이터를 가공된 형태로 변환하는 데 유용하다.
이러한 텍스트 처리 능력은 로그 파일 분석, 설정 파일 파싱, 데이터 리포트 생성 등 다양한 실용적인 작업에 적용된다. 복잡한 프로그래밍 언어 없이도 몇 줄의 awk 스크립트로 강력한 데이터 필터링과 가공 파이프라인을 구성할 수 있다는 점이 주요 장점이다.
awk의 핵심 강점 중 하나는 구조화된 텍스트 데이터에서 원하는 정보를 정확하게 추출하고, 필요에 따라 그 형식을 변환하는 능력이다. 이는 주로 정규 표현식을 활용한 패턴 매칭과 필드 단위의 연산을 조합하여 이루어진다. 사용자는 특정 패턴을 포함하는 행만 선택하거나, 특정 필드의 값을 기준으로 데이터를 걸러낼 수 있다. 예를 들어, 로그 파일에서 특정 시간대의 기록만 추출하거나, CSV 파일에서 특정 열의 값이 조건을 만족하는 행만 출력하는 작업이 여기에 해당한다.
데이터 변환은 추출된 정보를 가공하여 새로운 형태로 만드는 과정이다. awk는 필드 구분자를 변경하거나, 필드의 순서를 재배열하며, 계산을 통해 새로운 값을 생성하는 기능을 제공한다. 가장 간단한 예로, 공백으로 구분된 데이터를 쉼표로 구분된 형식으로 변환하거나, 여러 필드의 값을 조합하여 하나의 문자열을 생성할 수 있다. 또한, 합계나 평균 같은 집계 연산을 수행하여 데이터를 요약하는 보고서를 생성하는 데에도 널리 사용된다.
이러한 추출과 변환 작업은 주로 패턴과 액션 모델 안에서 이루어진다. 사용자는 처리할 행을 지정하는 패턴과, 그 행에 대해 수행할 조작을 정의하는 액션을 작성한다. 액션 블록 내에서는 내장 변수를 활용해 현재 행의 정보에 접근하고, 연산자와 함수를 사용해 데이터를 변환하며, printf 문을 이용해 깔끔하게 형식화된 결과를 출력할 수 있다. 이를 통해 복잡한 데이터 처리 파이프라인을 단일 awk 명령어로 간결하게 구현하는 것이 가능해진다.
awk는 단순한 텍스트 필터링을 넘어서 구조화된 보고서를 생성하는 데 매우 효과적이다. 데이터를 특정 형식으로 가공하고, 합계나 평균과 같은 통계를 계산하며, 가독성 높은 형태로 출력할 수 있다.
보고서 생성의 핵심은 데이터를 그룹화하고 집계하는 데 있다. awk는 연관 배열을 활용하여 특정 필드를 키로 사용해 데이터를 그룹별로 모을 수 있다. 예를 들어, 판매 데이터에서 상품명을 키로 사용해 판매량을 누적하거나, 로그 파일에서 IP 주소별 접속 횟수를 세는 작업이 가능하다. 이렇게 모은 데이터는 END 패턴을 사용해 모든 입력 처리가 끝난 후 한꺼번에 포맷을 맞춰 출력할 수 있다.
출력 형식을 제어하기 위해 printf 문을 주로 사용한다. printf를 이용하면 필드 너비, 정렬, 소수점 자릿수 등을 세밀하게 지정할 수 있어 표 형태의 깔끔한 보고서를 만들 수 있다. 또한, 구분자나 헤더 라인을 삽입하여 가독성을 높일 수 있다.
따라서 awk는 복잡한 프로그래밍 없이도 로그 분석, 간단한 회계, 실험 데이터 요약 등 다양한 분야에서 빠르게 유용한 보고서를 만들어내는 도구로 널리 쓰인다.

awk의 기본적인 사용법은 텍스트 파일의 각 줄을 읽어 필드로 나누고, 지정한 패턴에 맞는 줄에 대해 액션을 수행하는 것이다. 기본 출력은 print 문을 사용하며, 이는 전체 줄이나 특정 필드를 출력한다. 필드는 공백이나 탭과 같은 구분자로 나뉘며, 기본 구분자는 공백이다. 각 필드는 $1, $2, $3과 같이 달러 기호와 숫자로 참조할 수 있으며, $0은 전체 줄을 나타낸다.
예를 들어, awk '{print $1}' 파일명 명령은 주어진 파일의 각 줄에서 첫 번째 필드만 출력한다. 필드 구분자를 변경하려면 -F 옵션을 사용한다. awk -F',' '{print $2}' 파일명은 쉼표로 구분된 파일에서 두 번째 필드를 추출한다. 기본적으로 print 문은 출력 시 각 항목을 공백으로 구분하고, 줄 바꿈을 추가한다.
여러 필드를 동시에 출력하거나 사용자 정의 구분자를 넣을 수도 있다. awk '{print $3, $1}' 파일명은 세 번째 필드와 첫 번째 필드를 공백으로 구분해 출력한다. 출력 필드 구분자를 변경하려면 OFS 내장 변수를 설정한다. awk 'BEGIN{OFS=":"} {print $1, $2}' 파일명은 첫 번째와 두 번째 필드를 콜론으로 구분하여 출력한다.
간단한 계산이나 필드 조작도 기본 출력과 함께 자주 사용된다. awk '{print $1, $2+10}' 파일명은 첫 번째 필드와 두 번째 필드에 10을 더한 값을 출력한다. 이처럼 awk는 최소한의 코드로 텍스트 데이터에서 필요한 부분을 빠르게 추출하고 가공하는 데 유용하다.
awk는 조건에 따라 특정 행이나 필드를 처리하는 데 매우 효과적이다. 조건은 패턴 부분에 명시하며, 해당 조건을 만족하는 행에 대해서만 액션이 실행된다.
가장 기본적인 조건은 특정 필드의 값을 비교하는 것이다. 예를 들어, 첫 번째 필드의 값이 "apple"인 행만 출력하려면 awk '$1 == "apple" {print $0}' file.txt와 같이 사용한다. 숫자 비교도 가능하여, 세 번째 필드가 100보다 큰 행을 출력하려면 awk '$3 > 100' file.txt라고 작성할 수 있다. 여기서 액션인 print $0(전체 행 출력)은 생략 가능하다.
조건은 논리 연산자 &&(AND), ||(OR), !(NOT)를 사용해 복합적으로 구성할 수 있다. 예를 들어, 첫 번째 필드가 "error"이고 두 번째 필드가 5보다 큰 행을 찾으려면 awk '$1 == "error" && $2 > 5' log.txt와 같은 명령을 사용한다. 또한, 정규 표현식을 패턴으로 사용할 수 있어 특정 패턴을 포함하는 행을 검색하는 데 유용하다. awk '/error/' file.txt는 "error" 문자열이 포함된 모든 행을 출력한다.
조건부 처리는 텍스트 처리 및 필터링의 핵심으로, 데이터에서 필요한 정보만을 선별적으로 추출하거나 변환하는 작업에 필수적이다. 이를 통해 간단한 명령어로 복잡한 로그 분석이나 데이터 정제 작업을 자동화할 수 있다.
awk에서 배열은 연관 배열(associative array)로 구현된다. 이는 인덱스로 숫자뿐만 아니라 문자열도 사용할 수 있는 데이터 구조이다. 이 특징은 텍스트 데이터에서 키를 기반으로 값을 그룹화하거나 카운트하는 작업에 매우 효율적이다.
배열의 기본 사용법은 간단하다. array[index] = value 형태로 값을 할당하고, array[index]로 접근한다. 배열의 모든 요소를 순회할 때는 for (index in array) 구문을 사용한다. 이때 index는 배열의 키(인덱스)가 순차적으로 할당된다. 내장 함수 length(array)를 사용하면 배열에 저장된 요소의 개수를 알 수 있다.
배열은 로그 파일 분석이나 데이터 집계에 자주 활용된다. 예를 들어, 각 사용자별 접속 횟수를 세거나, 도시별 판매량을 합산하는 작업에 적합하다. 키로 문자열을 사용할 수 있기 때문에 복잡한 해시 테이블을 별도로 구현하지 않고도 직관적으로 데이터를 처리할 수 있다.
awk의 배열은 다차원 배열을 공식적으로 지원하지 않지만, 인덱스 문자열을 구분자로 연결하여(예: array[i, j]) 유사하게 구현할 수 있다. 이는 내부적으로 단일 문자열 인덱스(i SUBSEP j)로 처리된다. SUBSEP는 내장 변수로, 기본값은 제어 문자이다.

gawk는 GNU 프로젝트의 일환으로 개발된 awk의 자유 소프트웨어 구현체이다. GNU 일반 공중 사용 허가서(GPL) 하에 배포되며, 표준 awk의 모든 기능을 포함하면서도 여러 확장 기능을 제공한다. 리처드 스톨만이 GNU 프로젝트를 위해 작성하기 시작했으며, 현재는 앨프 에호와 폴 루빈 등이 유지보수하고 있다.
gawk는 원본 awk와의 호환성을 유지하면서도 국제화, 네트워크 통신, 정렬된 배열 반복, 시간 함수, 비트 조작 함수 등 다양한 확장 기능을 추가했다. 또한 명령줄 옵션도 더 풍부해져 사용자 편의성을 높였다. 이러한 특징으로 인해 현대 Unix 계열 시스템에서 'awk' 명령어는 대부분 gawk를 가리키는 경우가 많다.
gawk는 스크립트 파일 실행, 디버깅, 프로파일링과 같은 고급 기능도 지원한다. POSIX 표준을 준수하면서도 그 이상의 기능을 제공하기 때문에, 복잡한 텍스트 처리 및 데이터 변환 작업에 널리 사용된다. 리눅스 배포판을 비롯한 많은 시스템의 기본 awk 구현체로 채택되어 있다.
nawk는 원본 awk의 향상된 버전으로, "새로운 awk"를 의미한다. 1985년에 앨프 에호, 피터 J. 와인버거, 브라이언 커니핸이 awk의 기능을 확장하여 개발했다. 이 버전은 원본 awk의 제한 사항을 해결하고, 사용자 정의 함수, 다차원 배열, 향상된 입출력 기능 등 강력한 프로그래밍 기능을 추가했다.
nawk는 특히 더 복잡한 텍스트 처리와 데이터 변환 작업에 적합하도록 설계되었다. 사용자 정의 함수 기능은 코드의 재사용성과 모듈화를 높였으며, 향상된 배열은 데이터를 보다 유연하게 관리할 수 있게 했다. 이러한 확장은 awk를 단순한 명령줄 도구를 넘어 본격적인 스크립팅 언어의 영역으로 끌어올렸다.
nawk의 문법과 기능은 이후 POSIX 표준의 awk 명세에 큰 영향을 미쳤다. 오늘날 가장 널리 사용되는 gawk (GNU awk)를 포함한 많은 현대 awk 구현체는 nawk의 확장 기능을 기반으로 하고 있다. 따라서 nawk는 awk 언어 발전의 중요한 이정표로 평가된다.
현재 nawk는 유닉스 시스템의 표준 유틸리티로 포함되어 있으며, IEEE Std 1003.1-2008 (POSIX) 표준의 일부로 명세되어 있다.

awk는 그 이름의 유래가 개발자들의 성(Aho, Weinberger, Kernighan)의 첫 글자를 따서 만들어졌다는 점이 종종 회자된다. 이는 유닉스 철학의 전통을 따르는 동시에, 도구 자체가 가진 실용적인 성격을 상징적으로 보여준다.
프로그래밍 언어로서의 위상과는 별개로, awk는 수많은 시스템 관리자와 개발자에게 있어서 명령줄에서 빠르게 텍스트를 가공하는 데 없어서는 안 될 '스위스 아미 나이프' 같은 존재로 여겨진다. 복잡한 Perl이나 Python 스크립트를 작성하기에 앞서, 간단한 데이터 추출이나 형식 변환 작업에는 여전히 awk 한 줄 명령어가 먼저 떠오르는 경우가 많다.
awk의 문법과 접근 방식은 이후에 등장한 여러 데이터 처리 도구와 언어에 지대한 영향을 미쳤다. 특히, 유닉스 철학의 한 축을 이루며, 파이프라인과 함께 사용될 때 그 진가를 발휘하는 점은 현대의 커맨드 라인 인터페이스 문화에도 깊이 녹아들어 있다.
