Devin.KR
로그인

리눅스 cut 명령어 사용법 - 필드 잘라내기와 awk 로 넘어가야 할 때

개발자 조회 1

이 명령어를 언제 쓰는가

구분자로 나뉜 텍스트에서 특정 열만 뽑을 때 쓴다. /etc/passwd에서 계정명만, CSV에서 3번째 열만, 로그 한 줄에서 앞 15자만 잘라내는 식이다. awk 로도 전부 되지만 cut 은 옵션이 사실상 세 개뿐이라 파이프라인 중간에 끼워 넣었을 때 의도가 한눈에 읽힌다.

대신 cut 이 못 하는 일도 분명하다. 연속된 공백을 하나의 구분자로 묶지 못하고, 필드 순서도 바꾸지 못한다. 그 선을 넘는 순간 awk 로 갈아타는 것이 맞다. 이 경계를 알고 쓰는 것이 cut 을 제대로 쓰는 것이다.

기본 형식

cut -d '구분자' -f 필드번호 [파일]
  • -d — 필드를 나누는 문자 한 개. 생략하면 탭이다.
  • -f — 뽑을 필드 번호. 1, 1,3, 2-4, 3-(3번부터 끝까지) 형태를 모두 받는다.
  • 파일을 생략하면 표준 입력을 읽는다. 그래서 파이프 뒤에 그냥 붙이면 된다.

구분자가 아니라 위치로 자르려면 -c(문자)나 -b(바이트)를 쓴다. 이때 -d는 의미가 없다.

자주 쓰는 옵션

옵션의미예시
-d C구분자 문자 지정. 기본값은 탭cut -d: -f1 /etc/passwd
-f LIST필드 번호. 콤마와 범위를 섞어 쓸 수 있다cut -d, -f1,3-5 a.csv
-c LIST문자 위치로 자른다cut -c1-15 /var/log/syslog
-b LIST바이트 위치로 자른다. 고정폭 바이너리성 데이터용cut -b1-8 fixed.dat
-s구분자가 없는 줄은 아예 출력하지 않는다cut -d: -s -f1 /etc/passwd
--complement지정한 필드를 빼고 나머지를 출력한다 (GNU 전용)cut -d, --complement -f2 a.csv
--output-delimiter=S출력 구분자를 바꾼다 (GNU 전용)cut -d: -f1,7 --output-delimiter=' ' /etc/passwd

--complement--output-delimiter는 GNU coreutils 에만 있다. macOS 나 FreeBSD 의 BSD cut 에서는 cut: illegal option -- - 로 그냥 실패한다.

실전 예제

1) 서버에 어떤 계정이 있는지 훑는다. cut 의 교과서적 용례다.

cut -d: -f1 /etc/passwd

2) 계정과 로그인 셸을 같이 본다. 침해 사고 점검에서 nologin 이어야 할 계정이 셸을 갖고 있는지 확인할 때 쓴다.

cut -d: -f1,7 /etc/passwd

Ubuntu 에서의 출력은 이런 형태다.

root:/bin/bash
daemon:/usr/sbin/nologin
bin:/usr/sbin/nologin
www-data:/usr/sbin/nologin

3) 실제로 로그인 가능한 계정만 추린다. grep 으로 거르고 cut 으로 뽑는 조합이다.

grep -vE '(nologin|/bin/false)$' /etc/passwd | cut -d: -f1

4) CSV 한 열의 값 분포를 센다. 주문 데이터에서 상태값별 건수를 확인하는 상황이다.

cut -d, -f3 orders.csv | sort | uniq -c | sort -rn | head

5) 연속 공백으로 구분된 출력에서 열을 뽑는다. cut 단독으로는 안 되므로 tr -s 로 공백을 하나로 눌러 준 뒤 자른다.

df -P | tr -s ' ' | cut -d' ' -f6
Mounted
/
/dev
/run

6) 로그의 타임스탬프 부분만 잘라 시간대별 건수를 센다. 고정폭 로그라면 필드 파싱 없이 문자 위치로 끝난다.

cut -c1-9 /var/log/syslog | uniq -c | tail -n 20

함정과 주의점

구분자는 정확히 한 글자이고, 연속 구분자를 묶지 않는다. psdf처럼 공백으로 자리를 맞춘 출력에 cut -d' ' -f2 를 걸면 대부분 빈 줄이 나온다. 공백 두 개 사이의 빈 필드까지 필드로 세기 때문이다.

$ echo "root     1  0.0" | cut -d' ' -f2

$ echo "root     1  0.0" | awk '{print $2}'
1

awk 는 연속 공백을 하나로 보므로 이 경우 답은 awk 다. 굳이 cut 을 쓰겠다면 앞의 예제 5처럼 tr -s ' ' 를 먼저 통과시켜야 한다.

필드 순서를 바꿀 수 없다. cut -f3,1 이라고 써도 출력은 원본 순서인 1번, 3번이다. 열 순서를 바꾸려면 awk -F, '{print $3","$1}' 를 써야 한다. 이걸 모르고 cut 결과를 그대로 다른 시스템에 넣었다가 열이 뒤바뀐 채 적재되는 사고가 실제로 난다.

구분자가 없는 줄은 통째로 출력된다. 주석이나 빈 줄이 섞인 설정 파일을 cut 으로 자르면 주석 줄이 그대로 결과에 섞여 들어온다. -s 를 붙이면 그런 줄은 버린다.

-c-b는 한글에서 다르게 동작하고, 구현마다도 다르다. BSD(macOS) cut 의 -c 는 UTF-8 로케일에서 문자 단위로 정확히 자르지만, GNU cut 의 -c 는 사실상 바이트 단위라 한글이 깨질 수 있다. 한글이 섞인 데이터를 위치로 자르는 것은 처음부터 피하고, 필드나 정규식으로 접근하는 편이 안전하다.

함께 보면 좋은 명령어

  • awk — 연속 공백 처리, 열 순서 변경, 조건 필터가 필요해지면 여기로 넘어간다.
  • paste — cut 으로 뽑은 열들을 다시 옆으로 붙일 때 짝이 되는 명령이다.
  • tr — 구분자를 정리하거나 연속 공백을 눌러서 cut 이 먹히게 만드는 전처리에 쓴다.