잘못된 질문에 정확히 답하는 것보다
올바른 질문에 대략적으로 답하는 것이 낫다.

미국의 저명한 통계학자 존 튜키(John Wilder Tukey)가 한 말입니다. 흔히 데이터는 존재 자체가 아닌 활용에 가치가 있다고 하죠. 주어진 데이터에서 어떤 인사이트를 발견했을 때 데이터가 유의미해지는 것입니다.

여러분이 분석해야 할 미지의 데이터가 있다고 해 봅시다. 그 데이터는 얼마나 올바를까요? 존 튜키의 말을 되새겨 보세요. 올바른 데이터여야 대략적인 분석 결과라도 의미가 있을 것입니다. 오늘 소개할 책은 날 것의 텍스트 데이터를 정돈하고 분석해 주는, 간결하고 강력한 텍스트 처리 도구에 관한 것입니다.


1970년대의 일입니다. 텍스트 데이터를 효율적으로 처리할 수 있는 도구에 대한 필요성이 높아졌고, 이를 해결하기 위해 세 명의 천재 개발자가 한데 모여 AWK를 만들었습니다.

AWK는 간결한 문법과 강력한 패턴 매칭, 다양한 데이터 형식과 파일을 처리하는 유연성을 무기 삼아 텍스트 기반 데이터 처리를 혁신적으로 간소화했습니다. 앞에서 언급한 올바른 데이터를 얻기 위한 데이터 전처리 작업이나 탐색적 데이터 분석도 단 몇 줄의 코드로 구현할 수 있었습니다. 간결한 표현과 쉬운 사용법 덕분에 대형 프로그램의 프로토타입을 작성하는 데도 유용합니다. 처음에 몇 줄 짜 보고 의도한 결과가 나올 때까지 계속 프로그램을 조금씩 다듬거나 설계 대안을 재빨리 테스트해 볼 수도 있습니다.

이쯤이면 이렇게 질문할 사람이 있을 겁니다.

“이젠 AWK를 대신할 프로그래밍 언어가 많아! 굳이 AWK를 고집할 필요가 없지 않을까?”

네, 맞습니다. 오늘날에는 파이썬, 자바스크립트 등 다양한 프로그래밍 언어가 있지만, AWK는 여전히 그 가치가 유효합니다. 왜 일까요? 간단한 예를 들어보겠습니다.

(예시가 아주 간단합니다. 이 글을 쓰고 있는 편집자가 코알못이니 이해해 주기 바랍니다. 코드 작성에는 ChatGPT의 도움을 받았습니다. 아, 이 코알못 편집자도 이 책의 예제를 모두 실습했네요. AWK, 정말 쉽죠?)

어떤 파일(sample.txt)에서 특정 단어(error)가 포함된 줄 번호를 출력하는 코드를 작성해 보겠습니다. 먼저 awk 버전입니다.

awk '/error/ { print NR }' sample.txt

다음은 파이썬 버전입니다.

with open("sample.txt", "r") as file:
    for line_number, line in enumerate(file, start=1):
        if "error" in line:
            print(line_number)

AWK는 한 줄이면 끝났네요. 파이썬은 네 줄이네요. 책에 나오는 데이터로 해 볼까요? 타이타닉 승객 데이터에서 남녀 생존자를 계산하는 예제입니다. 이번엔 조금 더 깁니다. 먼저 AWK 버전입니다.

awk -F',' '
BEGIN { male=0; female=0; m_survived=0; f_survived=0 }
NR>1 {
    if ($5 == "male") {
        male++
        if ($2 == "1") m_survived++
    } else if ($5 == "female") {
        female++
        if ($2 == "1") f_survived++
    }
}
END {
    print "Male survivors:", m_survived, "/", male
    print "Female survivors:", f_survived, "/", female
}' titanic.csv

파이썬 버전입니다.

import csv

male = 0
female = 0
m_survived = 0
f_survived = 0

with open('titanic.csv', newline='') as csvfile:
    reader = csv.reader(csvfile)
    next(reader)  
    for row in reader:
        sex = row[4]
        survived = row[1]
        if sex == 'male':
            male += 1
            if survived == '1':
                m_survived += 1
        elif sex == 'female':
            female += 1
            if survived == '1':
                f_survived += 1

print(f"Male survivors: {m_survived} / {male}")
print(f"Female survivors: {f_survived} / {female}")

파이썬이 10줄 정도 더 많죠? 간단한 작업이지만 최소한의 구조를 갖춰야 하기 때문입니다. 여기선 파이썬으로 예를 들었지만 파이썬이 나쁘단 얘기는 아닙니다. 복잡한 데이터라도 간단한 도구로 해결할 수 있으면 그걸 써 보자는 이야기입니다. AWK가 바로 그렇습니다. 이 책에서는 다음과 같은 프로그램을 만들어 봅니다. 이 예시들을 보고 AWK를 여러분의 데이터에 어떻게 활용할 수 있을지 짐작해 볼 수 있다면 좋겠습니다.

이 책에서 작성해 보는 작은 프로그램들

  • 대륙별 국가 면적과 인구수 분석 프로그램
  • 주가 목록 스크래핑
  • 주소록에서 정보 가져오기
  • 색인(인덱스) 만들기
  • 걸음 수 달성 그래프 만들기
  • 무작위 텍스트 생성
  • 대화형 프로그램 만들기
  • 알고리즘 성능 테스트와 평가
  • 데이터 및 프로그램 유효성 검사

아, AWK는 앨프리드 에이호(Alfred V. Aho), 브라이언 커니핸(Brian W. Kernighan), 피터 와인버거(Peter J. Weinberger)의 이름을 한 자리씩을 따서 지었다고 합니다. (이름 짓기는 코드의 거장들도 어려운가 봅니다. 우리만 변수 이름을 고민하는 게 아니어서 다행입니다. 아, 말했었나요? 이 책은 AWK 창시자들이 직접 썼습니다. 어쩐지 실습이 불친절하더라고요. 뒤에 자세히 설명하겠습니다.)

이 책의 예제 파일은 다음에서 내려받을 수 있습니다.

여담이지만, 처음 실습을 하면서 약간 당황했습니다. 예제 코드들이 하나의 폴더 안에 불규칙하게 들어 있었기 때문입니다.

파일 이름만 봐서는 무엇이 awk 파일이고 입력 파일인지, 또한 무엇이 본문 예제 코드고 연습문제 정답인지 쉽게 파악할 수 없었습니다. 그래서 한국어판에서는 해당 파일을 쉽게 찾을 수 있도록 본문에 표시를 해 두었습니다. AWK 프로그램은 코드 안에 주석으로 표시했고(아래 그림에서는 quote가 파일명),

입력 파일(데이터)은 코드 블록 우측 상단에 표시해 두었습니다. (이 입력 파일의 이름은 titanic.tsv이겠죠?)

정답이 있는 연습문제는 해당 문제 옆에 정답 파일명을 적어 두었습니다. 실습 환경에 따라 출력 결과가 다르게 나올 수 있는데, 그럴 때는 적절히 각주를 넣었습니다.

자, 제가 이렇게 독자 여러분의 실습 시간을 확 줄여 놨으니 여러분은 AWK에 10분만 투자해 보세요. 만약 유닉스/리눅스 계열 운영체제를 사용하고 있다면 AWK는 이미 준비되어 있을 것입니다.

⟪AWK 프로그래밍 언어 2판⟫은 다음 서점에서 구입하실 수 있습니다.

교보문고 | 알라딘 | 예스24