본문으로 바로가기
Lab

tar 압축·해제 명령어 정리: gz·bz2·xz·zip 중 무엇을 고를까(macOS)

tar 압축 한 줄 명령과 글자별 뜻을 먼저 정리하고, 같은 폴더를 gzip·bzip2·xz·zip으로 묶은 결과를 비교했습니다. xz가 485040바이트로 가장 작았지만 2.2초로 가장 오래 걸렸습니다. 로그 빼기, 날짜 백업, Claude Code에게 명령을 맡긴 결과도 담았습니다.

·

폴더 하나가 크기가 서로 다른 다섯 개의 압축 상자로 눌려 담기는 개념 그림
tar 압축·해제 명령어 정리: gz·bz2·xz·zip 중 무엇을 고를까(macOS) 표지 삽화

같은 연습 폴더를 macOS 터미널에서 묶었더니 압축하지 않은 tar 파일은 33778176바이트, tar.xz는 485040바이트였습니다. 다만 tar.xz는 2.2초가 걸려서 0.2초에 끝난 tar.gz보다 한참 느렸죠. 배포 전에 프로젝트 폴더를 백업하거나 서버로 옮기려고 tar 압축 명령을 찾고 있다면, 이 기록을 보고 형식을 고를 수 있습니다.

폴더 하나를 압축 파일로 만드는 한 줄

폴더를 tar.gz로 만드는 명령은 tar -czvf 결과.tar.gz 폴더입니다. 풀 때는 c 자리에 x를 써서 tar -xzvf project.tar.gz처럼 쓰고, 특정 폴더에 풀려면 -C 폴더를 붙입니다. bsdtar 매뉴얼은 -x를 아카이브의 내용을 디스크로 꺼내는(extract) 옵션으로, -C를 x 모드에서 지정한 디렉터리로 옮겨 가서 푸는 옵션으로 설명합니다. 다만 이번 기록에서는 푸는 명령을 직접 실행하지 않았습니다. tar는 원래 여러 파일을 하나로 묶는 도구입니다. GNU tar 설명서도 아카이브를 여러 파일의 내용을 담으면서 이름과 소유자 같은 정보까지 기록하는 파일 하나로 설명하죠. 압축은 따로 붙이는 글자가 맡습니다.

  • c: 새 아카이브를 만듭니다(--create).
  • z: gzip으로 압축합니다. bzip2는 j, xz는 대문자 J를 씁니다.
  • v: 처리하는 파일 이름을 화면에 보여 줍니다. 아래 출력에서 a project/... 줄이 이 옵션 때문에 나옵니다.
  • f: 바로 뒤에 오는 이름으로 아카이브 파일을 씁니다.

실제로 project 폴더를 묶은 명령과 출력은 이렇습니다.

$ tar -czvf project.tar.gz project && ls -l project.tar.gz
a project
a project/docs
a project/logs
a project/src
a project/src/main.py
a project/src/data.txt
a project/logs/app.log
a project/docs/readme.md
-rw-r--r--@ 1 finn  wheel  3020962 Oct 27 16:41 project.tar.gz
tar 명령에 붙는 글자 c, z/j/J, v, f, t와 각 뜻을 정리한 표
`tar -czvf 결과.tar.gz 폴더`처럼 글자를 이어 붙여 쓰고, f 바로 뒤에는 만들 파일 이름을 씁니다.
도식출처: 직접 실행한 순서

결론부터 말하면, 이번 비교에서 가장 작은 파일은 tar.xz(485040바이트)였습니다. 압축하는 형식 가운데 tar.gz와 zip이 0.2초로 가장 빨리 끝났습니다(zip의 0.2초에는 크기를 확인하는 ls 명령까지 들어 있습니다). 압축 없이 묶기만 한 tar는 0.0초로 기록됐습니다.

함께 읽을 글

다섯 가지 형식은 크기와 시간이 얼마나 달랐을까요?

측정은 darwin arm64 맥에 기본으로 들어 있는 tar와 zip으로 했습니다. 맥의 tar는 GNU tar가 아니라 bsdtar라는 점부터 확인해 두세요.

$ tar --version
bsdtar 3.5.3 - libarchive 3.7.4 zlib/1.2.12 liblzma/5.4.3 bz2lib/1.0.8

연습 폴더에는 숫자 300만 줄짜리 텍스트, 로그 20만 줄, 작은 문서와 코드 파일을 넣었습니다. 아래 명령으로 그대로 만들 수 있어요.

$ mkdir -p project/src project/docs project/logs && seq 1 3000000 > project/src/data.txt && printf 'print("hello")\n' > project/src/main.py && printf '# 프로젝트\n설명 문서\n' > project/docs/readme.md && seq 1 200000 | sed 's/^/log line /' > project/logs/app.log && find project -type f | sort && du -sk project
project/docs/readme.md
project/logs/app.log
project/src/data.txt
project/src/main.py
32976	project

그다음 형식마다 글자 하나씩만 바꿔 묶었습니다. 압축 없는 묶음은 tar -cvf project.tar project, bzip2는 tar -cjvf project.tar.bz2 project, xz는 tar -cJvf project.tar.xz project입니다. 마지막으로 zip을 만들고 다섯 파일 크기를 한 번에 확인했습니다.

$ zip -rq project.zip project && ls -l project.tar project.tar.gz project.tar.bz2 project.tar.xz project.zip | awk '{print $5, $9}'
33778176 project.tar
2411461 project.tar.bz2
3020962 project.tar.gz
485040 project.tar.xz
3036987 project.zip
형식만든 명령의 핵심크기(바이트)걸린 시간
tar (압축 없음)tar -cvf337781760.0초
tar.gztar -czvf30209620.2초
tar.bz2tar -cjvf24114610.7초
tar.xztar -cJvf4850402.2초
zipzip -rq30369870.2초
tar 33778176바이트, zip 3036987바이트, tar.gz 3020962바이트, tar.bz2 2411461바이트, tar.xz 485040바이트를 비교한 막대 도식
darwin arm64 맥에서 같은 연습 폴더를 한 번씩 묶은 크기(바이트)입니다. 파일 내용에 따라 달라집니다.
도식출처: 근거를 바탕으로 코드가 그린 도식

그래서 무조건 xz를 쓰면 될까요? 이 폴더에서는 xz가 가장 작았지만 시간도 가장 오래 걸렸습니다. 왜 xz만 이만큼 작아졌는지는 이 측정만으로 가를 수 없어요. 파일 내용에 따라 결과가 달라지니, 자기 프로젝트 폴더로 같은 명령을 돌려서 ls -l로 크기를 비교해 보세요. tar.gz와 zip은 크기 차이가 크지 않았습니다. 받는 쪽이 윈도우 사용자처럼 zip이 편한 환경이라면 zip을 골라도 크기에서 크게 손해 보지는 않은 셈이죠.

크기를 확인했다면 다음은 그 안에 무엇이 들어갔는지 볼 차례입니다.

풀지 않고 안의 목록을 보는 방법

압축을 풀지 않고 내용만 보고 싶을 때는 c 자리에 t를 씁니다. bsdtar 매뉴얼은 -t를 아카이브 내용을 표준 출력에 나열하는 모드로 설명합니다.

$ tar -tzvf project.tar.gz
drwxr-xr-x  0 finn   wheel       0 Oct 27 16:41 project/
drwxr-xr-x  0 finn   wheel       0 Oct 27 16:41 project/docs/
drwxr-xr-x  0 finn   wheel       0 Oct 27 16:41 project/logs/
drwxr-xr-x  0 finn   wheel       0 Oct 27 16:41 project/src/
-rw-r--r--  0 finn   wheel      15 Oct 27 16:41 project/src/main.py
-rw-r--r--  0 finn   wheel 30666660 Oct 27 16:41 project/src/data.txt
-rw-r--r--  0 finn   wheel  3088895 Oct 27 16:41 project/logs/app.log
-rw-r--r--  0 finn   wheel       29 Oct 27 16:41 project/docs/readme.md

v를 함께 주면 권한, 소유자, 크기까지 나옵니다. 여기서 보면 data.txt가 30666660바이트로 대부분을 차지하죠. 참고로 bsdtar 매뉴얼은 bzip2와 xz 옵션 설명에서, 읽을 때는 압축 형식을 스스로 알아본다고 적고 있습니다. 다만 이번 기록에서는 z를 빼고 목록을 보는 경우를 따로 실행하지 않았습니다.

목록을 보면 로그 파일이 꽤 큰 것도 눈에 띕니다. 이럴 때는 로그를 빼고 묶으면 됩니다.

로그 파일만 빼고 묶는 방법

--exclude에 패턴을 주면 맞는 파일과 폴더를 처리하지 않습니다. bsdtar 매뉴얼은 이 제외 조건이 명령줄에 적은 파일 이름보다 우선한다고 밝힙니다.

$ tar --exclude='*.log' -czvf project-nolog.tar.gz project && ls -l project-nolog.tar.gz
a project
a project/docs
a project/logs
a project/src
a project/src/main.py
a project/src/data.txt
a project/docs/readme.md
-rw-r--r--@ 1 finn  wheel  2546812 Oct 27 16:41 project-nolog.tar.gz

출력을 보면 app.log는 빠졌지만 빈 project/logs 폴더는 그대로 들어갔습니다. 파일은 2546812바이트로, 로그를 넣은 tar.gz(3020962바이트)보다 작아졌죠. AI 코딩 도구로 작업하다 보면 실행 로그가 금방 쌓이니, 백업에서 무엇을 빼야 할지 먼저 목록으로 확인해 보는 편이 안전합니다.

날짜가 붙은 백업 파일 만들기

백업을 여러 번 만들 계획이라면 파일 이름에 날짜를 넣어 두면 덮어쓸 일이 줄어듭니다. 셸의 $(date +%Y%m%d)를 이름 안에 넣으면 됩니다.

$ tar -czf "backup-$(date +%Y%m%d).tar.gz" project && ls backup-*.tar.gz
backup-20261027.tar.gz

이번에는 v를 뺐습니다. 그래서 묶이는 파일 목록 없이 조용히 끝났고, 0.2초가 걸렸습니다. 스크립트나 예약 작업에 넣을 명령이라면 이렇게 출력을 줄이는 편이 기록을 읽기 편합니다.

옵션 순서를 바꿨을 때 생긴 오류

그런데 글자 순서를 무심코 -cfz로 쓰면 어떻게 될까요? 실제로 실행하면 종료 코드 1과 함께 이런 결과가 나옵니다.

$ tar -cfz project2.tar.gz project; ls -l z project2.tar.gz 2>&1
tar: project2.tar.gz: Cannot stat: No such file or directory
tar: Error exit delayed from previous errors.
ls: project2.tar.gz: No such file or directory
-rw-r--r--@ 1 finn  wheel  33778176 Oct 27 16:41 z

출력이 말해 주는 대로 f 바로 뒤의 z가 아카이브 이름이 됐습니다. 그래서 z라는 파일이 33778176바이트로 생겼는데, 압축 없는 project.tar와 같은 크기입니다. 반대로 원래 만들려던 project2.tar.gz는 묶을 대상 파일로 취급돼 찾을 수 없다는 오류가 났고요. 정리하면 f는 묶은 글자의 맨 끝에 두고, 그 바로 뒤에 파일 이름을 쓰면 됩니다.

옵션 블록 c, f, z 가운데 f가 바로 옆 z를 출력 파일 이름으로 붙잡고, 원래 만들려던 파일 이름은 입력 더미로 밀려나는 개념 그림
옵션 순서를 잘못 썼을 때 일어나는 일을 나타낸 개념 그림입니다. 실제 화면이 아닙니다.

이런 실수는 사람이 직접 칠 때 자주 생깁니다. 그렇다면 AI 에이전트에게 명령을 맡기면 어떨까요?

Claude Code에게 백업 명령을 맡긴 결과

Claude Code 2.1.309에 --model opus를 주고, 명령 한 줄만 출력하라고 요청했습니다. 기록된 명령은 > cmd.txt && cat cmd.txt && sh cmd.txt처럼 &&로 이어져 있었습니다. 이번 실험에서는 출력을 파일로 받아 화면에 보여 주고 곧바로 실행했습니다(중간에 사람이 확인하는 단계는 없었습니다). 직접 따라 한다면 만들기·확인 단계와 실행 단계를 나눠, 화면에 나온 명령을 읽어 본 다음 실행하는 편이 좋습니다.

claude --model opus -p "맥 터미널에서 project 폴더를 logs 폴더만 빼고 오늘 날짜(YYYY-MM-DD)가 이름에 들어간 tar.gz 파일로 압축하는 명령 한 줄만 출력해. 설명이나 코드 블록 표시는 붙이지 마." > cmd.txt && cat cmd.txt

내용을 확인한 뒤에만 실행합니다.

sh cmd.txt && ls *.tar.gz
$ claude --model opus -p "맥 터미널에서 project 폴더를 logs 폴더만 빼고 오늘 날짜(YYYY-MM-DD)가 이름에 들어간 tar.gz 파일로 압축하는 명령 한 줄만 출력해. 설명이나 코드 블록 표시는 붙이지 마." > cmd.txt && cat cmd.txt && sh cmd.txt && ls *.tar.gz
tar --exclude='project/logs' -czf "project-$(date +%F).tar.gz" project
backup-20261027.tar.gz
project-2026-10-27.tar.gz
project-nolog.tar.gz
project.tar.gz

전체 6.6초가 걸렸고 project-2026-10-27.tar.gz가 만들어졌습니다. Claude Code는 로그 파일 패턴(*.log) 대신 project/logs 경로를 제외하고, 날짜는 %F로 넣었습니다. 다만 이 기록에서는 만들어진 파일의 목록을 열어 보지 않았어요. 에이전트가 만든 백업 명령을 쓴다면 cat으로 명령을 먼저 읽고, 실행 뒤에는 -t로 목록을 확인해 빠진 것이 맞는지 보는 순서를 권합니다.

측정 조건과 한계

크기와 시간은 darwin arm64 맥 한 대에서 이 연습 폴더로 한 번씩 잰 값입니다. 파일 내용이 달라지면 형식 사이의 순서와 차이도 달라질 수 있습니다.

  • 시간은 단계마다 명령 전체를 잰 값이라 뒤에 붙은 ls 같은 확인 명령도 포함됩니다.
  • zip의 0.2초에는 다섯 파일 크기를 확인한 명령까지 들어 있습니다.
  • 모든 실행은 macOS의 bsdtar 3.5.3으로 했습니다. 리눅스 서버의 GNU tar에서는 같은 명령을 실행하지 않았으니, 서버에서 쓸 때는 tar --version으로 어느 쪽인지 먼저 확인하세요.
  • 압축을 푸는 시간은 재지 않았습니다.

참고 자료