[Linux] awk을 활용한 데이터 필터링
리눅스 시스템에서 파일의 크기가 매우 큰 경우, vi
로 내용을 확인하기가 부담이 가는 경우가 있다. 근데 확인하고 싶은 내용이 파일의 앞쪽인 지 모르겠고, 뒷쪽인지도 잘 모르겠고, 즉 tail
과 head
를 사용하기에도 어려운 경우에는 awk
를 활용할 수 있다.
awk
awk
는 패턴 스캐닝 및 프로세싱 언어로, 텍스트 파일의 내용을 분석해서 패턴의 검색과 조작을 위한 목적으로 만들어졌다.
$ awk '패턴 { 행동 }' [파일명]
기본적으로 awk
는 입력 파일의 각 줄을 읽고, 주어진 패턴에 맞는 줄을 찾아 행동을 수행한다.
awk
은 정말 다양한 목적으로 사용될 수 있다.
- 파일의 특정 필드만 출력
- 패턴이 포함된 레코드 출력
- 다른 프로그램의 입력 형식에 맞게 변환하는 작업에 이용
- 특정 필드에 연산 수행 결과 출력
- 필드 값 비교에 따라 레코드 출력
- 특정 필드에 문자열을 추가하여 출력
등등등
특정 필드 출력하기
awk
를 이용해 1, 3 필드를 출력해보자. (만약 전체 필드를 출력하고자한다면 &0
인자를 사용한다)
$ awk '{print $1, $3}' data
hong 011-222-2222
park 017-333-3333
im 019-444-4444
son 016-555-5555
gil 018-666-6666
jang 011-7777-7777
lee 016-8888-8888
sa 017-9999-9999
hwang 015-555-5555
25세 이상인 사람의 이름과 나이를 출력해보자.
$ awk '$2>25{print $1, $2}' sample
park 28
yoon 46
kin 33
조건부 출력
awk
는 조건문을 사용해서 특정 조건을 만족하는 줄만 출력할 수 있다. 예를 들어 두번 째 필드가 100보다 큰 줄만 출력하려면 다음과 같이 작성할 수 있다.
$ awk '$2 > 100 { print }' filename.txt
아래의 sample에서 ‘세’ 글자를 없애고, 문장에 맞춰 출력해보자.
$ cat sample
sung 23세 010-1234-5678
park 28세 011-8765-4321
yoon 46세 010-4321-5678
kin 33세 016-1122-3344
la 15세 010-5555-5555
$ sed 's/세//g' sample | awk '$2>25{print $1"님은 ",$2"세 입니다."}'
park님은 28세 입니다.
yoon님은 46세 입니다.
kin님은 33세 입니다.
10시부터 10시 30분 사이의 로그를 출력해보자.(타입스탬프 형식이 "YYYY-MM-DD HH:MM:SS” 라고 가정)
awk '$2 >= "10:00:00" && $2 <= "10:30:00" { print }' filename.log
필드 구분자 지정하기
기본적으로 awk
은 공백을 필드 구분자로 사용하지만, 다른 구분자를 사용할 수도 있다. -F
옵션을 사용하면 필드 구분자를 지정할 수 있다. 예를 들어, 콤마(,)로 구분된 CSV 파일에서 두 번째 필드를 출력하려면 다음과 같이 작성한다.
$ awk -F, '{ print $2 }' filename.csv
awk
은 특히 매우 큰 용량의 로그 파일에서 특정 시간 대의 로그를 추출하고 싶을 때 많이 사용하고 있다. 단, 조건부 작성법이나 표현식을 모두 외우고 있기는 힘들기 때문에, 최근에는 gpt를 활용해 쉽게 작성할 수 있다.