리눅스 cut 명령어 사용법 - 필드 잘라내기와 awk 로 넘어가야 할 때
이 명령어를 언제 쓰는가
구분자로 나뉜 텍스트에서 특정 열만 뽑을 때 쓴다. /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
함정과 주의점
구분자는 정확히 한 글자이고, 연속 구분자를 묶지 않는다. ps나 df처럼 공백으로 자리를 맞춘 출력에 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 이 먹히게 만드는 전처리에 쓴다.