sed와 awk는 리눅스에서 텍스트 처리를 위한 대표적인 유틸리티입니다. sed(stream editer)는 비대화형 모드의 텍스트 파일 에디터이고, awk는 C 언어 형태의 문법을 가지는 필드 단위의 패턴 처리 언어입니다. awk는 sed에 비해 다양한 패턴과 액션 함수들을 가지고 있고, 배열 및 변수(내부 및 사용자 정의)를 가지고 있습니다. 또한, 내장 변수를 사용해 다양한 형태의 입출력이 가능합니다. 따라서, awk는 복잡한 만큼 다양하게 활용될 수 있습니다.




sed

sed의 동작 방식은 다음과 같습니다. sed는 한 번에 한 라인만 처리하고 모니터로 출력합니다. sed는 한 라인씩 패턴 공간이라고 부르는 임시 버퍼에 보내지고 처리됩니다. 그리고 처리된 라인은 모니터로 출력하고 임시 버퍼에는 다음 라인이 저장됩니다.

기본 정규표현식을 사용하고, 여러 sed 연산자 p(print), d(delete), s(substitute), g(global)가 있습니다. 예시로 s/d$//g는 각 줄에서 d로 끝나는 문자가 나올 때마다 공백(삭제)으로 치환하라는 의미를 가집니다.




awk

리눅스에서 사용하는 awk는 GNU 버전의 gawk로 심볼릭 링크되어 있습니다. awk의 기본 형식은 awk ‘pattern{action}’ filename 입니다. 이때, pattern{action}은 여러 개가 올 수 있습니다. 세미콜론(;) 또는 뉴라인(newline)을 통해 분리됩니다. 만일 입력 파일이 지정되지 않으면 키보드에 의한 표준 입력을 받게 됩니다. 패턴은 정규표현식(확장된), 참과 거짓 상태의 결과 또는 이들의 결합으로 구성되어 있습니다. 패턴 표현식을 읽을 때 암시적으로 if 문장이 되고 기본적으로 참인(true)인 상태입니다. 그리고 액션은 기본적으로 {print $0}입니다. 따라서, ‘awk 파일’을 입력하면 ‘cat 파일’과 똑같이 동작하는 것처럼 보입니다.

동작 방식은 sed와 비슷합니다. $0라는 내부 변수에 라인을 저장합니다. newline에 의해 구분됩니다. 그리고 나서, FS(filed separate, default FS는 공백)을 기준으로 각각의 필드로 나누어집니다. 각 필드는 번호가 매겨지고 $1로 시작합니다. 내부 변수 OFS(default=공백)는 output FS로 print 함수를 사용할 시 콤마(,)와 매핑되어 있습니다.

ORS, RS도 있습니다. 레코드 분리자로 잘 사용하지 않지만, 두 내부 변수를 사용하여 입출력의 레코드를 구분합니다.


출력함수

출력 함수로는 대표적으로 print와 printf가 있습니다. 공통적으로, 문자열은 큰따옴표로 둘러싸야 합니다. 개인적으로 더 깔끔한 포맷팅이 되는 printf 함수를 선호합니다. print 함수는 default action으로 액션이 지정되지 않고 패턴이 매칭된다면, 매칭된 라인을 출력합니다({print $0}).


awk -f

awk은 특정한 파일에 명령(패턴과 액션)을 저장해두고 이 파일에 입력된 명령을 사용하여 원하는 텍스트 파일을 처리합니다. 여러 묶음(패턴{액션})이 있다면, 세미콜론 또는 newline으로 구분합니다. 이때, 열기 컬리 브레이스는 패턴과 같은 라인에 두어야 합니다.


연산자

match 연산자는 틸드(~)로 표기되며, 하나의 레코드에서 특정 필드 부분만 정규표현식으로 매칭하고 싶을 때 사용됩니다(DML에서 LIKE 연산자와 비슷합니다). 패턴과 액션에서는 쉘 연산자와 다르게 프로그래밍 언어에서 사용되는 비교, 대입, 산술, 논리 연산자를 사용할 수 있습니다. 추가적으로, 증가/감소 연산자(++,–)를 사용할 수도 있습니다.


내부 변수와 사용자 정의 변수

내부 변수는 빌트인 내장 변수를 말하며 FS, RS, NF(현재 레코드에서 전체 필드 수), NR(현재까지 레코드 수), FILENAME 등이 있습니다. 사용자 정의 변수는 문자열과 숫자형이 있으며 awk는 사용자가 변수를 초기화 하지 않으면, 자동으로 0과 null로 초기화합니다.


BEGIN, END패턴

BEGIN 패턴은 awk가 입력 파일의 라인들을 처리하기 이전에 실행되며 액션 블록 앞에 씁니다. 그래서 입력 파일 없이 실행할 수 있습니다. 주로 필드 변수들을(내부 변수, 사용자 저의 변수) 초기화하거나 헤더 및 타이틀을 작성할 때 쓰입니다.

END 패턴은 입력의 모든 라인이 처리되고난 후에 실행됩니다. BEGIN과 다르게 파일명을 적어주어야 합니다. 주로 액션에서 처리한 결과들을 정리해서 출력할 때 쓰입니다.


awk 리다이렉션

awk 액션에서 출력 리다이렉션을 사용하여 모니터가 아닌 파일로 출력할 수 있습니다. awk 프로그램이 종료될 때까지 오픈된 상태로 유지됩니다(파이프도 END패턴이 끝날 때까지 오픈되어 있습니다). 입력 리다이렉션의 경우, getline 함수와 함께 써서 getline에 한 라인씩 저장합니다. getline은 파이프 라인과도 자주 함께 쓰입니다. ‘BEGIN{ “date” | getline d; print d }’ 처럼 date 명령어 결과값을 한 라인씩 변수 d에 저장합니다. 추가적으로, 명령어 및 파일명은 항상 큰따옴표(““)로 감싸주어야 합니다.


기타

awk 액션에서는 다양한 명령 옵션이 있고 C언어에서 사용하는 if문, for문(특별 for문), while문 그리고 배열을 사용할 수 있고 다양한 awk 빌트인 함수들이 있지만, 모두 정리하기엔 너무 방대하기에 이번 포스트에선 awk의 기본적인 부분들을 정리하고자 합니다.