우분투 실전 명령어 | awk 컬럼 분석과 즉석 집계

서버 로그나 CSV 비슷한 텍스트를 빠르게 집계해야 할 때 awk 하나로 대부분 해결할 수 있다. grep으로 줄을 고른 뒤 awk로 컬럼을 뽑아 합계나 빈도를 바로 확인하면 장애 분석 속도가 확 올라간다.

언제 쓰는가

  • access.log에서 상태코드별 요청 수를 즉시 볼 때
  • ps 출력에서 메모리 많이 쓰는 프로세스를 상위 N개로 볼 때
  • 공백 구분 텍스트에서 특정 컬럼만 추출해 후속 파이프에 넘길 때

바로 쓰는 명령어

# 상태코드(9번째 필드)별 요청 수 집계
awk '{count[$9]++} END {for (code in count) print code, count[code]}' access.log | sort -n
# 응답 바이트(10번째 필드) 합계와 평균
awk '{sum+=$10; n++} END {if(n>0) printf "sum=%d avg=%.2f\n", sum, sum/n; else print "no data"}' access.log
# 콤마 구분 파일에서 2,4번째 컬럼만 출력
awk -F',' '{print $2 "," $4}' users.csv

핵심 옵션/패턴

  • -F: 필드 구분자 지정. CSV면 -F',' 처럼 명시한다.
  • $1, $2: n번째 필드 참조. $0은 전체 라인이다.
  • 조건 패턴: $9 >= 500 {print $0} 처럼 필터와 액션을 같이 쓴다.
  • END 블록: 전체 입력을 다 읽은 뒤 합계, 평균, 요약 출력에 사용한다.
  • 연관 배열: count[key]++ 패턴으로 빈도 집계할 때 가장 자주 쓴다.

명령 출력 예시

$ awk '{count[$9]++} END {for (code in count) print code, count[code]}' access.log | sort -n
200 15230
301 412
404 93
500 7
$ awk '{sum+=$10; n++} END {if(n>0) printf "sum=%d avg=%.2f\n", sum, sum/n; else print "no data"}' access.log
sum=98345123 avg=6321.66

자주 하는 실수

  • CSV를 기본 공백 구분으로 처리해서 컬럼이 틀어지는 실수
    • 증상: $2 값이 기대와 다르거나 통째로 붙어 나온다.
    • 해결: -F',' 또는 TSV면 -F'\t'를 명시한다.
  • 숫자 컬럼에 -, "-", 공백이 섞여 있는데 바로 합산하는 실수
    • 증상: 합계가 비정상적으로 작거나 0으로 치우친다.
    • 해결: $10 ~ /^[0-9]+$/ 조건으로 숫자만 더한다.
  • 헤더 라인을 데이터로 함께 집계하는 실수
    • 해결: NR==1 {next}로 첫 줄을 건너뛴다.

검증 방법

# 상태코드 집계 검증: 전체 줄 수와 집계 합이 같은지 확인
wc -l access.log
awk '{count[$9]++} END {for (c in count) s+=count[c]; print s}' access.log
# 숫자 아닌 바이트 값이 있는지 점검
awk '$10 !~ /^[0-9]+$/ {print NR, $10}' access.log | head

운영 팁

트래픽이 큰 로그는 전체 파일 대신 최근 구간부터 확인하는 게 빠르다. 예를 들어 tail -n 200000 access.log | awk ... 식으로 최근 데이터만 먼저 보고, 이상 징후가 보이면 기간을 넓혀 재집계하면 된다.

출처

  • GNU Awk Manual
  • Ubuntu Manpages
  • NGINX Documentation