Linux

[Linux] awk을 활용한 데이터 필터링

nayoungs 2024. 11. 20. 00:13
728x90

리눅스 시스템에서 파일의 크기가 매우 큰 경우, vi 로 내용을 확인하기가 부담이 가는 경우가 있다. 근데 확인하고 싶은 내용이 파일의 앞쪽인 지 모르겠고, 뒷쪽인지도 잘 모르겠고, 즉 tailhead 를 사용하기에도 어려운 경우에는 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를 활용해 쉽게 작성할 수 있다.

 

728x90