cut은 줄마다 바이트(-b), 문자(-c), 필드(-f) 중 하나의 기준으로 정해진 위치만 잘라 표준 출력으로 내보내는 필터 명령어다. /etc/passwd처럼 구분자로 나뉜 시스템 파일이나 CSV·로그에서 특정 열만 뽑아낼 때 가장 먼저 손이 가는 도구다.
이 장을 읽기 전에
선행 챕터: 이 장은 15장: awk에서 레코드·필드를 패턴과 액션으로 처리하는 법을 다룬 뒤 이어진다. awk가 조건·연산·재배열까지 가능한 만능 텍스트 처리 언어였다면, cut은 그중 “필드 하나 뽑기"라는 가장 단순한 작업만 떼어내 가볍게 처리하는 도구다. awk가 강력하지만 무겁다면, cut은 단순 컬럼 추출만 할 때 쓰는 가벼운 도구라고 이해하면 된다.
이 장의 깊이: 입문 난이도다. 옵션 자체가 많지 않아 표 하나로 전체 문법을 파악할 수 있다. 다루지 않는 것: 구분자가 여러 문자이거나 정규식이어야 하는 상황, 필드를 원본과 다른 순서로 재배열하는 작업, 조건부 필터링은 cut의 설계 범위 밖이라 15장: awk로 돌아가야 한다. 잘라낸 필드나 문자를 다른 문자로 바꾸는 작업은 17장: tr에서 다룬다.
당신의 수준에 맞는 경로
| 수준 | 읽을 부분 | 핵심 목표 |
|---|---|---|
| CSV·passwd에서 열 하나만 급하게 뽑아야 하는 사람 | “개요 + 정신 모델”, “사용법 · 옵션"의 “필드 선택”, “예시"의 “필드 추출” | -d와 -f를 조합해 원하는 열을 즉시 뽑아낼 수 있다 |
| cut의 한계를 정확히 알고 awk와 구분해 쓰려는 사람 | “주의사항·함정”, “흔한 오개념” 전체 | 단일 구분자·필드 재배열 불가·멀티바이트 이슈를 이해하고 언제 awk로 넘어가야 하는지 판단할 수 있다 |
개요 + 정신 모델
cut의 세상은 줄마다 똑같이 적용되는 위치 규칙 하나로 이루어져 있다. “몇 번째 바이트인가”, “몇 번째 문자인가”, “구분자로 나눴을 때 몇 번째 필드인가” — 이 세 가지 중 정확히 하나만 고르고 나면, cut은 그 규칙을 모든 입력 줄에 기계적으로 반복 적용할 뿐 그 이상은 하지 않는다. 조건을 걸어 특정 줄만 고르거나(awk의 패턴), 잘라낸 값을 계산하거나(awk의 연산), 필드 순서를 뒤바꾸는 일은 애초에 cut이 풀도록 설계된 문제가 아니다.
이 단순함이 곧 cut의 정체성이다. POSIX 사양은 cut을 “각 줄에서 지정한 바이트·문자·필드만 골라 그대로 출력하는” 유틸리티로 정의하며, 선택된 항목은 입력에 나타난 순서 그대로 기록된다고 명시한다. 즉 cut은 스트림을 읽고 판단하는 프로그램이 아니라, 매 줄에 똑같은 “자” 하나를 대고 잘라내는 재단기에 가깝다. 옵션을 외우기보다 “이 재단기에는 눈금이 하나뿐이다"라는 사실을 먼저 받아들이면 뒤에서 다룰 함정(필드 재배열 불가, 단일 구분자 한계)이 왜 생기는지 자연스럽게 이해된다.
사용법 · 옵션
| |
- 파일: 생략하면 표준 입력에서 읽는다. 여러 파일을 지정하면 파일 구분 없이 순서대로 이어서 처리한다.
-b,-c,-f중 정확히 하나만 지정해야 한다. 두 개 이상을 함께 쓰면 오류가 난다.
위치 선택 (-b, -c, -f 중 하나)
| 옵션 | 설명 |
|---|---|
-b LIST, --bytes=LIST | 바이트 위치 기준으로 자른다. 멀티바이트 문자를 중간에서 자를 수 있다 |
-c LIST, --characters=LIST | 문자 위치 기준으로 자른다. 로케일을 인식해 멀티바이트 문자를 하나로 센다 |
-f LIST, --fields=LIST | 구분자로 나눈 필드 위치 기준으로 자른다 |
-n | -b와 함께 써서 멀티바이트 문자를 중간에서 자르지 않게 한다(GNU coreutils 확장) |
LIST는 1(1번째), 1,3(1번째와 3번째), 1-3(1–3번째), 3-(3번째부터 끝까지), -3(처음부터 3번째까지)처럼 콤마로 여러 항목을, 하이픈으로 범위를 지정하는 공통 문법을 쓴다.
구분자 · 출력 제어
| 옵션 | 설명 |
|---|---|
-d DELIM, --delimiter=DELIM | -f와 함께 쓰는 필드 구분자. 기본값은 탭. 한 글자만 지정할 수 있다 |
-s, --only-delimited | -f와 함께 쓰며, 구분자가 아예 없는 줄은 출력하지 않고 건너뛴다(기본값은 그런 줄도 그대로 통과시킨다) |
--complement | 선택한 위치를 제외한 나머지를 출력한다(선택 반전) |
-O STRING, --output-delimiter=STRING | 출력할 때 쓸 구분자를 따로 지정한다(기본은 입력 구분자를 그대로 재사용) |
-z, --zero-terminated | 줄바꿈 대신 NUL 문자를 줄 구분자로 쓴다(파일명처럼 개행이 포함될 수 있는 데이터용) |
예시
필드 추출
| |
문자·바이트 위치
| |
선택 반전 · 출력 구분자 변경
| |
파이프 조합
| |
구분자 없는 줄 처리
| |
주의사항·함정
-d는 한 글자 구분자만 지원한다. cut -d, -f1처럼 콤마 하나는 되지만, 연속된 공백 여러 개를 하나의 구분자로 묶어 처리하는 것은 고전적인 cut의 설계 범위 밖이다. ps -eo pid,comm처럼 오른쪽 정렬로 값이 패딩되는 출력에 공백을 구분자로 쓰면, 값 앞의 공백들이 각각 빈 필드로 잡혀 원하는 열이 엉뚱한 번호로 밀린다.
| |
GNU coreutils는 9.4(2023년)부터 -w(--whitespace-delimited) 옵션으로 공백 연속을 한 구분자로 묶어 처리하는 기능을 추가했지만, 이는 POSIX 표준에 없는 GNU 확장이라 오래된 시스템이나 BSD 계열 cut에는 없을 수 있다. 이식성을 고려해야 하거나 애초에 공백 개수가 일정하지 않은 입력이라면 awk '{print $2}'처럼 awk의 기본 필드 분리(연속 공백을 자동으로 하나로 묶음)를 쓰는 편이 안전하다 — 15장: awk가 필요한 이유가 바로 이 지점이다.
필드를 지정한 순서대로 재배열할 수 없다. POSIX 사양은 “선택된 바이트·문자·필드는 선택 목록의 순서가 아니라 입력 데이터의 순서대로 출력된다"고 명시한다. 즉 cut -f3,1 file.txt를 실행해도 결과는 3번, 1번 순서가 아니라 원본 그대로인 1번, 3번 순서로 나온다. 열 순서를 바꿔서 출력하고 싶다면(예: 3번째 필드를 1번째 필드보다 먼저 보여주기) cut으로는 불가능하고 awk '{print $3, $1}'을 써야 한다 — 이 차이가 “cut은 자르기만 하고, awk는 자르고 재조합까지 한다"는 두 도구의 역할 분담을 가장 잘 보여준다.
멀티바이트(UTF-8 한글 등) 환경에서 -c와 -b의 결과가 다르다. -c는 로케일을 인식해 “글자 하나"를 기준으로 세지만, -b는 인코딩과 무관하게 순수 바이트 수만 센다. UTF-8 로케일에서 한글 한 글자는 보통 3바이트를 차지하므로, cut -c1-3은 한글 3글자를 온전히 잘라내지만 cut -b1-3은 한글 1글자의 중간 바이트에서 잘려 깨진 문자가 출력될 수 있다. GNU cut은 -n 옵션으로 -b를 쓸 때도 멀티바이트 문자 중간을 자르지 않도록 보정할 수 있지만, -n은 -b와 함께일 때만 의미가 있고 -c에는 애초에 해당하지 않는다. 로케일이 C나 POSIX로 설정된 환경(스크립트 초반에 LC_ALL=C를 흔히 거는 이유 중 하나)에서는 -c도 사실상 바이트 단위로 동작하므로, 한글이 섞인 텍스트를 다룰 때는 현재 로케일(locale 명령으로 확인)이 UTF-8인지 먼저 확인하는 습관이 필요하다.
흔한 오개념
"-d에 정규식이나 여러 문자를 넣을 수 있다"는 오해가 흔하다. awk의 FS(필드 구분자)는 정규식을 받아들이지만, cut -d는 정확히 한 글자만 구분자로 인정한다. cut -d", " -f1처럼 여러 문자를 넣으면 대부분의 cut 구현은 오류를 내거나 첫 글자만 구분자로 취급한다. 구분자가 문자열이거나 패턴이어야 하는 상황이라면 애초에 cut이 아니라 awk -F 또는 sed를 선택해야 한다.
다음 장에서는
다음은 17장: tr — cut으로 잘라낸 문자·필드를 이번에는 다른 문자로 바꾸거나 삭제하는 문자 단위 변환을 다룬다.
평가 기준
-b,-c,-f세 가지 위치 선택 기준의 차이를 설명하고 상황에 맞게 고를 수 있다.-d와-f를 조합해 CSV·/etc/passwd처럼 구분자로 나뉜 텍스트에서 원하는 열을 추출할 수 있다.cut이 필드를 입력 순서대로만 출력하며 재배열할 수 없다는 한계를 설명하고, 재배열이 필요할 때 awk로 전환할 판단을 할 수 있다.cut -d가 단일 문자 구분자만 지원한다는 제약과, 연속 공백을 하나로 묶어야 하는 상황에서 왜 awk가 더 적합한지 설명할 수 있다.- UTF-8 등 멀티바이트 환경에서
-c와-b의 결과가 달라질 수 있다는 점을 이해하고 로케일을 점검할 수 있다.
![Featured image of post [Bash Shell] 16. cut - 컬럼 추출](/post/bashshell/cut-command-extract-columns-linux/wordcloud_hu_3ba086147d61af39.webp)
![[Bash Shell] 14. sed - 스트림 편집](/post/bashshell/sed-command-stream-editor-linux/wordcloud_hu_7ec28326489f97a8.webp)
![[Bash Shell] 15. awk - 레코드·필드 처리](/post/bashshell/awk-command-text-processing-field-records/wordcloud_hu_7ec28326489f97a8.webp)
![[Bash Shell] 16. cut - 컬럼 추출](/post/bashshell/cut-command-extract-columns-linux/wordcloud_hu_7ec28326489f97a8.webp)
![[Bash Shell] 17. tr - 문자 치환·삭제](/post/bashshell/tr-command-translate-delete-characters/wordcloud_hu_7ec28326489f97a8.webp)
![[Bash Shell] 18. sort, uniq, wc - 정렬·중복 제거·개수 세기](/post/bashshell/sort-uniq-wc-commands-sort-count-lines/wordcloud_hu_7ec28326489f97a8.webp)
![[Bash Shell] 13. grep - 패턴 검색](/post/bashshell/grep-command-search-text-pattern-linux/wordcloud_hu_7ec28326489f97a8.webp)
![[Bash Shell] 03. cat, head, tail - 파일 내용 출력과 일부 보기](/post/bashshell/cat-head-tail-commands-view-file-contents/wordcloud_hu_7ec28326489f97a8.webp)
![[Bash Shell] 04. less, more - 페이저로 파일 보기](/post/bashshell/less-more-commands-view-large-files-linux/wordcloud_hu_7ec28326489f97a8.webp)