AWK 열 추출

LinuxBeginner
지금 연습하기

소개

Linux 에서 로그 파일, CSV 파일, 구성 파일처럼 구조화된 텍스트 데이터를 다룰 때는 특정 정보 열만 추출해야 하는 경우가 많습니다. 예를 들어 시스템 파일에서 사용자 이름만 가져오거나 웹 액세스 로그에서 상태 코드만 추출할 수 있습니다.

이 작업의 대표적인 도구가 awk입니다.

awk는 텍스트를 레코드 (행) 와 필드 (열) 의 연속으로 처리합니다. 이것이 일반 텍스트가 Linux 에서 여전히 유용한 이유 중 하나입니다. 많은 관리용 데이터 형식은 눈으로 확인하기 쉽고 명령줄 도구로 처리하기도 쉽습니다.

  • 레코드는 일반적으로 줄바꿈으로 구분됩니다.
  • 필드는 일반적으로 공백 문자 (스페이스 또는 탭) 로 구분됩니다.

이 "레코드와 필드" 모델을 이해하면 awk를 훨씬 쉽게 사용할 수 있습니다. 파일을 단순한 텍스트 덩어리로 보는 대신, awk는 직접 참조할 수 있는 구조화된 행과 열로 봅니다.

이 실습에서는 다음과 같은 awk 사용법을 배웁니다.

  1. 필드 선택: $1, $2 등을 사용해 특정 열을 추출합니다.
  2. 필드 구분자 지정: -F 옵션을 사용해 공백이 아닌 문자 (콜론 또는 쉼표 등) 로 구분된 데이터를 처리합니다.
  3. 마지막 필드 참조: $NF를 사용해 줄의 끝에 있는 필드에 동적으로 접근합니다.

첫 번째 필드 추출

간단한 공백 구분 파일부터 시작합니다. 실습 환경에 data.txt 파일을 준비해 두었습니다.

파일 내용을 확인합니다.

cat data.txt

출력:

John 25 Engineer
Alice 30 Manager
Bob 22 Intern

awk에서는 각 줄이 하나의 레코드이고 각 단어가 하나의 필드입니다.

  • 필드 1 ($1): 이름 (예: John)
  • 필드 2 ($2): 나이 (예: 25)
  • 필드 3 ($3): 역할 (예: Engineer)

이름, 즉 첫 번째 열만 추출하려면 awk에 $1을 출력하도록 지정합니다.

awk에서 $1, $2와 같은 표현식은 현재 레코드의 필드를 가리킵니다. $0은 현재 줄 전체를 의미합니다. 이러한 필드 표기법 덕분에 awk는 구조화된 텍스트를 간결하게 처리할 수 있습니다.

다음 명령을 실행합니다.

awk '{print $1}' data.txt

출력:

John
Alice
Bob

이제 이 출력을 파일에 저장합니다.

awk '{print $1}' data.txt > output1.txt

새 파일의 내용을 확인합니다.

cat output1.txt

필드 구분 방식 이해

이번에는 다른 형식의 파일인 /etc/passwd를 사용합니다. 이 파일에는 사용자 계정 정보가 저장되어 있습니다.

passwd 파일의 앞부분을 확인합니다.

head -n 3 /etc/passwd

출력은 다음과 비슷합니다. root:x:0:0:root:/root:/bin/bash

공백이 없다는 점에 주의합니다. 대신 필드가 콜론 (:) 으로 구분되어 있습니다.

이 파일에서 기본 awk 명령을 실행하면 필드가 올바르게 분리되지 않습니다. 기본적으로 공백을 기준으로 필드를 나누기 때문입니다.

다음 명령을 실행해 봅니다.

awk '{print $1}' /etc/passwd > output2.txt
head -n 3 output2.txt

전체 줄이 출력되는 것을 확인할 수 있습니다. awk가 공백을 찾지 못해 전체 줄을 하나의 필드 ($1) 로 처리했기 때문입니다.

이 문제를 해결하려면 사용자 지정 필드 구분자를 지정해야 합니다.

이 내용은 실제 텍스트 처리에서 중요한 교훈입니다. 도구는 데이터 형식을 얼마나 정확히 이해하고 사용하는지에 따라 제대로 동작합니다. 잘못된 구분자를 선택하면 추출했다고 생각한 열과 awk가 실제로 인식한 열이 달라집니다.

사용자 지정 필드 구분자 (-F) 사용

콜론으로 구분된 데이터를 사용할 수 있는 필드로 변환하려면 -F 플래그를 사용합니다.

awk -F: 명령은 열 사이의 구분자로 콜론 문자를 사용하도록 awk에 지정합니다.

-F 옵션은 출력이나 조건 처리를 수행하기 전에 awk가 각 줄을 구문 분석하는 방식을 변경합니다. 줄이 올바르게 분리되면 $1, $7과 같은 필드 참조를 다시 의미 있게 사용할 수 있습니다.

이제 특정 필드를 추출할 수 있습니다. /etc/passwd 파일에서 다음 필드를 사용합니다.

  • 필드 1 은 사용자 이름입니다.
  • 필드 7 은 셸입니다.

사용자 이름과 셸만 추출해 보겠습니다. 쉼표로 구분해 여러 필드를 출력할 수 있습니다.

awk -F: '{print $1, $7}' /etc/passwd > output3.txt

결과를 확인합니다.

head -n 5 output3.txt

출력은 다음과 비슷해야 합니다. root /bin/bash

awk가 콜론을 기준으로 줄을 올바르게 분리한 뒤 첫 번째 필드와 일곱 번째 필드를 출력했으며, 출력에서는 두 필드가 공백으로 구분됩니다.

마지막 필드 ($NF) 출력

줄에 열이 정확히 몇 개 있는지 모르거나 줄마다 열 개수가 달라질 수 있는 경우가 있습니다. 하지만 필요한 데이터가 항상 마지막 열에 있다는 사실은 알고 있을 수 있습니다.

awk는 $NF라는 내장 변수 (Number of Fields) 를 제공합니다.

  • NF는 현재 줄의 필드 개수를 저장합니다.
  • $NF는 마지막 필드의 값을 가리킵니다.

이 기능을 사용하면 명령이 특정 열 번호에 덜 의존하게 됩니다. 절대적인 열 번호보다 뒤에서부터의 위치가 중요할 때 NF와 $NF가 더 유연하게 작동하는 경우가 많습니다.

$NF를 사용해 /etc/passwd의 마지막 열을 추출합니다.

awk -F: '{print $NF}' /etc/passwd > output4.txt

출력을 확인합니다.

head -n 5 output4.txt

파일 구조가 일관적이라면 $7을 사용했을 때와 마찬가지로 셸 (예: /bin/bash) 이 출력되어야 합니다. $NF는 줄의 끝에 자동으로 맞춰지므로 더 견고한 방법인 경우가 많습니다.

요약

이 실습에서는 awk로 텍스트를 구문 분석하는 기본 방법을 배웠습니다.

  1. 필드 추출 ($N): $1, $2 등을 사용해 데이터의 개별 열에 접근합니다.
  2. 필드 구분자 (-F): -F 옵션을 사용해 콜론이나 쉼표처럼 서로 다른 구분자로 나뉜 파일을 처리합니다.
  3. 마지막 필드 ($NF): 레코드의 마지막 열에 동적으로 접근합니다.

이러한 기법을 사용하면 원시 구조화 텍스트를 후속 처리에 사용할 수 있는 깔끔한 데이터 스트림으로 변환할 수 있습니다.