[Linux] AWK 간단 정리

  • AWK 는 데이터를 다루는 사람들이라면 한번씩은 그 Command를 사용해봤을 것입니다.
  • 저는 과거 Dataframe 을 생성해 본격적인 분석 및 연구.개발 작업이 들어가기 전에, AWK 를 통해 간단한 데이터 처리를 하는 경우, Raw Data 형식을 간단하게 정제하여 Database에 적재하는 경우에 사용해 왔습니다. 이 경우, 많이 사용하는 관용적인 구문외에는 AWK 자체를 살펴볼 기회가 적었습니다.
  • 최근 사내에서 로그 데이터의 추출을 위해 AWK를 오랜만에 다시 사용하게 되면서, 잊었던 AWK문법을 다시 한 번 살펴보며, 이번 기회에 AWK의 간단 사용예제부터 AWK 문법 몇가지를 정리해보고자 합니다.

AWK (Aho Weinberger Kernighan 오크)

  • 스크립트 언어
  • 텍스트 파일을 조회/필터링/가공 출력하는 프로그램
  • 쉘스크립트 상에서 데이터를 간단히 처리할 수 있는 필수 프로그램
  • 각 row data는 Enter(줄바꿈, newline)로 구분, column data는 공백, tab으로 구분
  • 각 row data, 줄은 레코드(Record) 라 지칭
  • 각 데이터, column, 단어 등은 필드(Field) 라 지칭

AWK 의 동작방식

  1. 필드 전체 : $0, 특정 필드 지칭 : $1 ~ (주의 : 0번이 첫번째가 아님!!)
  2. 기본적인 default 구분자는 **공백(Space, Tab)**이나, -F 옵션을 줌으로써 구분 기호를 지정가능
  3. AWK command 형식 : awk {pattern} {action} filename
    1. pattern, action 둘 중 한 값만 있으면 됨

AWK 사용예제

1. Column data 추출

  • 각 Column 은 $1 와 같은 형태로 필드에 접근하여 추출 할 수 있습니다.
1
2
3
4
5
# awk {action} filename 형식
awk '{print $1}' ./file_you_want.log

# $0 전체 column 추출
awk '{print $0}' ./file_you_want.log

2. 특정 Pattern : 정규표현식

  • 문자열 중에 ADID 라는 글씨가 포함된 레코드를 출력해주는 커맨드입니다.
1
awk '/ADID/' ./platform.log 

→ 출력 예시 : 20211207 ADID1234556 123$456 device3 window

  • AWK pattern에는 정규표현식을 사용할 수 있습니다.
    • pattern내에 정규표현식 구분은 /regular expression/ (슬래쉬)로 이루어집니다.
1
$ awk '/[A-Z][a-z]+/' ./system.log

3. AWK Command : if구문

  • 특정 조건에 맞는 구문을 뽑을 때, 다음과 같이 사용할 수 있습니다.
  • 다음은 3번 필드의 값이 1과 같을 때 전체 레코드를 뽑는 커맨드 입니다.
1
awk '{if ($3 == 1) print ($0)}' ./system.log

→ 출력 예시 :

20211207 ADID123456 1 device3 window

20211207 ADID123654 1 device2 android

20211207 ADID654321 1 device1 ios

  • 다음은 1번 필드가 20211206과 같고 3번 필드가 2이상인 전체 레코드를 뽑는 커맨드입니다.
    • 이처럼, if 구문 안에 다양한 조건들과 &&(and) ||(or), !(not) 을 활용할 수 있습니다.
1
awk '{if ($1 == 20211206 && $3 >= 2) print($0)}' ./system.log

→ 출력 예시 :

20211206 ADID123456 2 device2 window

20211206 ADID654321 3 device3 ios

20211206 ADID432561 4 device2 android

  • ? , : 의 기능 : if-else 구문
    • if 구문 → $1 else $2 라는 뜻입니다.
1
2
$ awk '{조건 ? $1 : $2}' ./system.log

4. AWK Command : for 구문

  • AWK 구문에서도 필요시 다음과 같이 for문을 사용할 수 있습니다.
1
2
3
4
awk '{
for (i=0;i<2;i++)
print()
}'

5. AWK BEGIN, END

  • BEGIN과 END는 AWK 구문이 시작되기 전, 마친 후에 수행되는 커맨드입니다.
  • 다음 커맨드는 {count++} 가 수행되기 전과 후에 Start, End 를 알리고, Count 를 세는 커맨드 입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
awk '
BEGIN {
print("Begin Processing...")
count = 0
}
{
count++
}
END {
print("COUNT: " count)
print("End Processing")
}' ./system.log
'

AWK 정의 변수

  • AWK 에서는 사용자의 편의를 위해 자체적으로 정의된 변수가 몇가지 있습니다. 미리 정의된 변수를 AWK command 안에서 다양하게 활용할 수 있습니다. 다음은 AWK에서 정의된 변수들중 많이 사용되는 몇가지를 추려보았습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
  ARGV        : command line argument 배열
ARGC : ARGV 배열 요소의 갯수
CONVFMT : 포맷팅 형식 (example: 숫자 포맷팅 형식)
ENVIRON : 환경변수 배열
FILENAME : 파일 이름 (경로포함)
FS : 필드 구분자 (default: space)
NF : 필드의 갯수
NR : 현재 레코드의 순서
OFMT : 문자열 출력 형식
OFS : 필드 구분자 (default: space)
ORS : 레코드 구분자 (default: newline)
RLENGTH : match 함수에 의해 매칭된 문자열의 길이
RS : 레코드 구분 문자 (default: newline)

쉘파이프 안에서의 AWK

  • 위의 사용예제들처럼 Linux CLI 환경에서 AWK command의 강력함은 확인 할 수 있었습니다. 이 외에도 쉘스크립트, 쉘파이프 안에서 AWK 를 활용하고, argument 를 전달하는지는 다음의 예제에서 확인 할 수 있습니다.
  • AWK command 에서 argument를 넘겨 줄 때는 -v 옵션을 사용하여 넘겨 줄 수 있습니다.
1
2
3
test_variable="hello"
$ echo | awk -v output=$test_variable '{ print "TEST VARIABLE : " output}'
TEST VARIABLE : hello

Untitled

  • AWK command 를 상세하게 알고 싶다면, 그 동작 원리와 구조 또한 살펴볼게 많이 있습니다. 각자의 활용 정도에 따라 더욱 필요한 요소를 아래 reference 등의 자료를 통해 공부할 수 있을 것입니다.
  • 이번 기회를 통해 짧게나마 AWK 를 정리 할 수 있었고, 활용 snippet code 를 남김으로써 다음 재사용시 빠르게 활용할 수 있을 것으로 기대됩니다.

Reference

  • AWK 내에 정의된 함수와 변수 등을 자세히 알고 싶다면, 다음 documentation 을 참조하실 수 있습니다.

The GNU Awk User’s Guide

리눅스 awk 명령어 사용법. (Linux awk command) - 리눅스 파일 텍스트 데이터 검사, 조작, 출력.

Author

Emjay Ahn

Posted on

2021-12-07

Updated on

2021-12-07

Licensed under

Comments