리눅스나 유닉스 명령줄 환경에서 awk, sed, grep은 많은 개발자와 시스템 관리자가 가장 사랑하는 도구 세 가지입니다. 세 도구 모두 강력한 기능을 갖추고 있지만, 이번 글에서는 그중 awk에 집중해 보겠습니다. awk의 기본 사용법부터 시작해서, 실무에서 바로 활용할 수 있는 유용한 awk 원라이너(한 줄 스크립트)까지 차근차근 살펴보겠습니다.
AWK란 무엇인가?
AWK는 파일이나 데이터 스트림에 담긴 텍스트 기반 데이터를 처리하기 위해 설계된 프로그래밍 언어입니다. 1970년대 벨 연구소(Bell Labs)에서 탄생했는데, 나이가 꽤 된 언어라고 해서 얕보지 마세요. 텍스트 처리 분야에서는 지금도 매우 강력하고 효율적인 성능을 자랑합니다. 이제 본격적으로 awk의 세계로 들어가 보겠습니다.
기본 사용법 익히기
복잡한 내용으로 넘어가기 전에 먼저 awk의 기초를 다져 보겠습니다. 이 실습에서는 간단한 샘플 파일 하나를 만들어 사용할 것입니다. 시스템 로그 파일처럼 어떤 텍스트 파일이든 활용할 수 있습니다. 여기서는 필자가 즐겨 사용하는 시스템 모니터링 도구인 Dstat의 출력 결과를 예제로 사용하겠습니다.
Dstat 출력은 콤마나 탭으로 구분된 데이터이기 때문에 awk가 처리하기에 이상적인 형태입니다. 곧 그 이유를 알게 될 것입니다. 위와 같은 데이터를 직접 만들거나 예제를 복사해 test.txt라는 이름의 더미 파일로 저장하세요.
그다음 리눅스 컴퓨터에서 터미널 창을 엽니다. 거의 모든 리눅스 배포판에는 awk가 기본적으로 포함되어 있지만, 혹시 설치되어 있지 않다면 패키지 관리자를 통해 설치하면 됩니다. test.txt 파일이 있는 디렉터리에서 아래 명령어를 입력해 보세요.
# awk '{print}' test.txt
이 명령은 텍스트 파일의 전체 내용을 그대로 출력합니다. 물론 이것만으로는 재미가 없죠.
특정 열만 추출하기
이제 원하는 열(column)만 골라서 출력하는 방법을 알아보겠습니다. 다음 명령어를 실행해 보세요.
# awk '{print $1}' test.txt
이 명령은 파일의 첫 번째 열만 출력하도록 요청합니다. awk는 파일이 탭으로 구분되어 있다는 것을 자동으로 인식하고 첫 번째 열만 출력합니다. 결과는 다음과 같습니다.
---total-cpu-usage---
usr
5
13
8
0
1
1
1
0
1
1
같은 방식으로 어떤 열이든 출력할 수 있습니다. 세 번째 열을 출력하고 싶다면 명령어를 다음과 같이 바꾸면 됩니다.
# awk '{print $3}' test.txt
여러 열 동시에 출력하기
awk로 여러 열을 한 번에 출력할 수도 있습니다. 첫 번째, 세 번째, 일곱 번째 열을 함께 보고 싶다면 콤마로 구분해 나열하면 됩니다.
# awk '{print $1, $3, $7}' test.txt
실행 결과는 다음과 같습니다.
---total-cpu-usage--- -net/total-
usr idl read
5 93 154k
13 87 0
8 92 0
0 99 0
1 97 0
1 98 0
1 99 0
0 99 0
1 99 0
1 100 0
사용자 지정 구분자 활용하기
공백이나 탭 대신 콜론(:)으로 구분된 /etc/passwd 파일처럼 조금 까다로운 파일을 다룰 때는 awk가 구분자를 자동으로 인식하지 못합니다. 이런 경우에는 올바른 구분자를 직접 지정해 주면 됩니다. -F 옵션을 사용해 파일의 두 번째 필드를 출력하는 명령어는 다음과 같습니다.
# awk -F':' '{print $1}' /etc/passwd
이 명령을 실행하면 시스템에 등록된 모든 사용자 계정 이름이 출력됩니다.
apple
mango
banana
watermelon
kiwi
orange
콜론 외에도 어떤 종류의 구분자든 같은 방식으로 지정할 수 있습니다.
로그 파일 분석 실전 예제
awk는 로그 파일 분석에도 매우 유용합니다. 예를 들어 웹 서버에 접속한 모든 IP 주소와 해당 웹 URL을 확인하고 싶다면, 웹 서버의 접근 로그(access log)를 awk로 파싱하면 됩니다. 다음 명령어를 사용해 보세요.
# awk '$9 == 200 {print $1, $7}' access.log
이 명령은 HTTP 상태 코드가 200(성공)인 요청의 IP 주소와 요청 경로를 출력합니다.
199.63.142.250 /2008/10/my-5-favourite-hangouts/
220.180.94.221 /2009/02/querious-a-mysql-client-for-the-mac/
67.190.114.46 /2009/05/
173.234.43.110 /2009/01/bicycle-rental/
173.234.38.110 /wp-comments-post.php
이런 식으로 로그를 파싱하면 특정 사용자가 비정상적으로 자주 사이트를 방문하는지 확인할 수 있습니다. 정보를 무단 수집하려는 의심스러운 접근을 발견하는 데도 도움이 되죠.
IP별 방문 횟수 집계하기
분석 결과를 정렬할 수도 있습니다. 특정 IP 주소가 웹사이트를 몇 번이나 방문했는지 알고 싶다면 sort와 uniq 명령어를 파이프(|)로 연결해 사용하세요.
# awk '$9 == 200 {print $1}' access.log | sort | uniq -c | sort -nr
실행 결과는 다음과 같습니다.
46 122.248.161.1
35 122.248.161.2
26 65.202.21.10
24 67.195.111.46
19 144.36.231.111
18 59.183.121.71
여기까지 awk의 기본 문법과 열 추출, 구분자 지정, 로그 분석까지 살펴봤습니다. 이 기본기를 익혀두면 텍스트 데이터를 다루는 거의 모든 작업에서 awk를 강력한 무기로 활용할 수 있을 것입니다.