Computer >> 컴퓨터 >  >> 프로그래밍 >> Bash 프로그래밍

리눅스 awk 명령어 사용법 완벽 가이드 (실전 예제 포함)

이 가이드에서는 리눅스에서 awk 명령어를 사용하는 방법을 다양한 실전 예제와 함께 자세히 소개합니다.

AWK는 리눅스 운영체제에서 텍스트를 검색하고 조작할 수 있는 도구이자 프로그래밍 언어입니다.

awk 명령어와 관련 스크립팅 언어는 파일에서 패턴(pattern)으로 정의된 텍스트를 검색하고, 해당 패턴과 일치하는 텍스트에 대해 특정 동작(action)을 수행합니다.

awk는 대용량 텍스트 파일이나 수많은 텍스트 파일에서 데이터를 추출하고 보고서를 작성하는 데 매우 유용한 도구입니다. 예를 들어 로그 파일 처리나, 온도 센서처럼 오랜 기간 데이터를 수집한 장치의 출력 결과 분석에 활용할 수 있으며, 데이터베이스 쿼리 결과를 가공할 때도 사용됩니다.

awk는 별도로 설치할 필요가 없습니다. 대부분의 리눅스 시스템에는 이미 기본적으로 포함되어 있습니다.

awk 기본 문법

터미널에서 awk 명령어를 사용하는 기본 문법은 다음과 같습니다.

awk [PROGRAM] [INPUT FILES]

각 요소를 살펴보면 다음과 같습니다.

  • [PROGRAM]: 검색 패턴과 수행할 동작을 정의하는 부분으로, awk가 입력 파일에 실행할 프로그램입니다.
    • -f 옵션을 사용하면 인라인으로 작성하는 대신 텍스트 파일 형태로 프로그램을 전달할 수 있습니다.
  • [INPUT FILES]: awk가 처리할 대상 파일입니다. 공백으로 구분된 여러 파일, 디렉터리 경로, 또는 파일 패턴을 지정할 수 있습니다.
    • 입력 파일을 지정하지 않으면 다른 명령어의 파이프 출력 결과를 받아 처리합니다.

awk 주요 옵션

awk 명령어에 사용할 수 있는 주요 옵션은 다음과 같습니다.

옵션 설명
-f program-file 명령줄 대신 파일에서 프로그램 코드를 읽어옵니다. 여러 개의 -f 옵션을 동시에 사용할 수 있습니다.
-F value 필드 구분자(FS)를 지정한 값으로 설정합니다.
-v var=value 프로그램 변수 var에 값을 할당합니다.

사용 중인 awk 버전에 따른 추가 옵션이 궁금하다면 아래 명령어로 매뉴얼을 확인할 수 있습니다.

man awk

프로그램 구조와 변수

awk에 전달하는 프로그램이 텍스트 파일을 어떻게 처리할지 결정합니다. awk 프로그램은 다음과 같은 형식을 따릅니다.

CONDITION { ACTION }
CONDITION { ACTION }
...

여기서 CONDITION은 일치시킬 텍스트 패턴이고, ACTION은 매칭된 텍스트에 대해 수행할 동작입니다. 조건과 동작은 원하는 만큼 여러 개 지정할 수 있습니다.

동작(Action)

동작 부분에는 계산식, 변수, 함수 호출 등을 포함한 명령어를 작성할 수 있습니다. 일부 내장 함수는 구현체마다 다를 수 있으므로, 매뉴얼을 통해 확인하는 것이 좋습니다.

레코드(Record)

awk는 별도로 OPTIONS로 지정하지 않는 한, 텍스트 파일의 각 줄을 하나의 레코드(record)로 취급합니다.

필드(Field)

awk는 별도 설정이 없는 한 공백(스페이스, 탭)을 기준으로 레코드 내 필드(field)를 구분합니다.

내장 변수

awk는 직접 정의하지 않고도 바로 사용할 수 있는 다양한 내장 변수를 제공하여, 흔히 발생하는 상황들을 손쉽게 처리할 수 있게 해줍니다.

변수 의미
$0 현재 레코드 전체를 나타냅니다.
$1, $2, $3 … 필드 변수 – 레코드 내 개별 필드의 텍스트/값을 담습니다.
NR / Number of Records 지금까지 읽은 전체 입력 레코드의 개수입니다.
FNR / File Number of Records 현재 파일에서 지금까지 읽은 레코드 개수 – 새 파일을 시작할 때마다 0으로 자동 초기화됩니다.
NF / Number of Fields 현재 입력 레코드의 필드 개수 – 마지막 필드는 $NF, 뒤에서 두 번째 필드는 $(NF-1)로 참조할 수 있습니다.
FILENAME 현재 처리 중인 입력 파일의 이름입니다.
FS / Field Separator 레코드 내 필드를 구분하는 문자 – 기본값은 공백과 탭 문자입니다.
RS / Record Separator 파일 내 레코드를 구분하는 문자 – 기본값은 줄바꿈 문자입니다.
OFS / Output Field Separator awk 출력에서 필드를 구분하는 문자 – 기본값은 공백 한 칸입니다.
ORS / Output Record Separator awk 출력에서 레코드를 구분하는 문자 – 기본값은 줄바꿈 문자입니다.
OFMT / Output ForMaT 숫자 출력 형식 – 기본값은 “%.6g”입니다.

awk 사용 예제

아래 예제에서는 다음 내용을 담고 있는 flowers.txt라는 텍스트 파일 하나를 사용합니다.

red rose
yellow daffodil
pink flamingo
white rose
blue iris
white lily
red peony
yellow orchid
purple foxglove

파일 내용 출력하기

다음 awk 명령어는 print 함수를 사용해 파일 내용을 터미널에 그대로 출력합니다.

awk '{print}' flowers.txt

파일의 레코드(줄) 수 세기

awk 'END { print NR }' sample.txt

이 예제는 파일의 총 줄 수를 출력합니다.

9

정규표현식으로 텍스트 검색하기

다음 명령어는 파일에서 rose(장미)가 포함된 줄만 출력합니다.

awk '/rose/' flowers.txt

검색할 텍스트는 REGEX(정규표현식) 문법으로 정의한다는 점에 유의하세요.

실행 결과는 다음과 같습니다.

red rose
white rose

정규표현식 활용 심화

awk '/^p/' flowers.txt

이 명령어는 p로 시작하는 레코드만 출력합니다.

pink flamingo
purple foxglove

필드 변수 활용하기

필드 변수를 사용하면 p로 시작하는 레코드의 첫 번째 필드만 출력할 수 있습니다.

awk '/^p/ {print $1;}' flowers.txt

실행 결과는 다음과 같습니다.

pink
purple

다른 프로그램의 출력 결과 처리하기

다른 리눅스 셸 프로그램의 출력을 파이프(pipe)로 연결해 awk로 처리할 수 있습니다. 이 예제는 현재 디렉터리의 내용을 나열하는 ls -l 명령어의 출력에서 5번째 필드(파일 크기)를 추출합니다.

ls -l | awk '{print $5}'

실행 결과는 대략 다음과 같습니다.

3104
3072
224
256

…(현재 디렉터리에 있는 파일의 개수와 크기에 따라 달라집니다).

내장 변수 활용하기

awk '{print NR "-" $2 }' flowers.txt

이 명령어는 현재 레코드 번호(파일 줄 번호)와 두 번째 필드인 꽃 이름을 함께 출력합니다.

1-red rose
2-yellow daffodil
3-pink flamingo
4-white rose
5-blue iris
6-white lily
7-red peony
8-yellow orchid
9-purple foxglove

조건 결합하기

조건동작&& 연산자로 결합할 수 있습니다. 다음 명령어는 첫 번째 필드에 red라는 텍스트가 포함되고, 두 번째 필드가 5글자 미만인 모든 레코드를 출력합니다.

awk '$1 ~ /red/ && length($NF) < 5 { print }' flowers.txt

참고 사항:

  • $NF를 사용해 두 번째 필드에 접근했습니다. $2를 쓰는 것과 같은 결과인데, 이 필드가 마지막 필드이므로 NF(Number of Fields)와 같기 때문입니다.
  • length() 함수는 필드의 글자 수를 계산하는 데 사용됩니다.

따라서 예제 파일에서는 단 하나의 일치하는 레코드만 반환됩니다.

red rose

마무리

awk가 거의 모든 리눅스 배포판에 기본 탑재되어 있는 데에는 이유가 있습니다. 텍스트 검색과 처리를 위한 필수 도구로, 시스템에 문제가 생겼을 때 로그 항목을 빠르게 찾거나, 연구 목적으로 수집된 데이터를 가공하는 데 활용할 수 있습니다.

대량의 텍스트 파일에서 단순 찾기/바꾸기 이상의 작업을 해본 적이 있다면, 일일이 개별 명령어를 실행하지 않고도 프로그래밍 방식으로 모든 텍스트 파일에 일괄적으로 교체나 수정 작업을 적용할 수 있다는 것이 얼마나 큰 장점인지 실감하실 겁니다.

다른 리눅스 활용 팁도 확인해 보세요!