본문 바로가기
책상 노트 책상 노트
실무자가 실제로 굴려본 업무도구·업무 자동화 기록

2.5TB, 드라이브 7개, 삭제 전에 한 일 단 하나

읽는 시간 약 15분

내장 3대와 외장 1대, 그리고 USB 2개에 몇 년째 흩어져 있던 96만 개 파일, 용량으로 약 2.5TB를 이틀에 걸쳐 한 번에 정리했습니다. 결과는 삭제 약 330GB, 해시 검증 이관 약 590GB입니다. 손실은 0건입니다. 정리를 끝낸 뒤 드라이브 하나는 통째로 비워 백업 전용으로 돌렸습니다. 32GB USB는 아무것도 없는 이동용이 됐습니다.

이 작업에서 가장 중요했던 건 순서였습니다. 파일을 한 개라도 옮기거나 지우기 전에, 전 드라이브의 파일 목록부터 CSV로 만들어놓고 시작했습니다. 그리고 지우는 동작은 예외 없이 “복사 → SHA-256 해시 대조 → 그다음에 원본 삭제” 순서로 고정했습니다. 이 순서를 지킨 덕분에 잃은 파일이 없었습니다. 한 개도 없었습니다. 중간에 스크립트(이 글에 나오는 용어는 따로 모아 정리해 두었습니다)가 죽고, 프로그램이 강제 종료되고, 관리자 권한에 막히는 일이 이틀 사이에 여러 번 있었는데도 그랬습니다.

아래는 실제로 무엇에 막혔고 그걸 어떻게 처리했는지의 기록입니다. 개발자가 아니라 재무, 경영 실무를 보는 사람이 자기 데이터를 정리한 이야기입니다.

무엇이 어디에 쌓여 있는지 모르는 상태였습니다

시작 시점의 지형은 이랬습니다.

드라이브종류용량여유
C:내장299GB19GB
D:내장631GB202GB
E:내장931GB17GB
I:내장299GB18GB
H:외장2TB978GB
G:USB32GB10GB
N:클라우드 연동30GB8.6GB

문제가 눈에 보입니다. 두 가지입니다. 931GB짜리 드라이브에 여유가 17GB밖에 없는데, 정작 그 안에 무엇이 들어 있는지를 저는 하나도 몰랐습니다. 299GB짜리가 두 대라는 것도 그때 처음 알았습니다.

그래서 첫 작업은 삭제가 아니었습니다. 목록 만들기였습니다. 파일 경로와 크기, 수정 시각, 확장자까지 네 가지만 뽑아 CSV로 떨구는 스크립트를 돌렸습니다. 판단은 나중이었습니다. 일단 지도부터 만든 것입니다.

첫 스캔은 실패했습니다

7개 루트를 한 번에 스캔하는 명령을 걸어놨습니다. 종료 코드 1로 죽었습니다. 로그를 보니 이랬습니다.

“`

UnicodeEncodeError: ‘utf-8’ codec can’t encode character ‘\udf2d’

in position 55: surrogates not allowed

“`

원인은 파일명이었습니다. 외장하드 어딘가에 한글 인코딩이 깨진 채로 몇 년째 방치돼 있던 파일이 섞여 있었습니다. 그 깨진 이름을 CSV에 한 줄 쓰려는 순간, 인코딩 오류가 나면서 96만 개를 훑던 스크립트가 통째로 주저앉았습니다. 오래된 드라이브를 뒤지면 흔한 일입니다. 겪어보기 전에는 생각도 못 했습니다.

다행히 죽기 전에 4개 드라이브는 CSV를 다 써놓은 상태였습니다. 인코딩 처리만 보강해서 나머지 3개를 다시 돌렸습니다. 스캔에 걸린 실제 시간은 드라이브마다 크게 갈렸습니다.

  • USB 32GB(9,811개): 0.9초
  • 내장 631GB(106,159개): 1.8초
  • 외장 2TB(219,018개): 18.3초
  • 내장 931GB(525,525개): 899초, 약 15분

파일 개수가 많으면 용량과 무관하게 느려집니다. 용량이 아니라 개수입니다. 52만 개가 든 드라이브 하나가 전체 스캔 시간의 대부분을 혼자 먹었습니다.

전부 합쳐 7개 루트, 약 96만 파일, 2.5TB짜리 목록이 나왔습니다.

2.5TB를 이틀 동안 정리했는데 손실은 0건이었습니다
지우는 동작을 복사, 해시 대조, 원본 삭제 순서로 고정했습니다.

중복 찾기, 후보 41,388그룹에서 검증된 547.8GB

목록이 생기고 나서야 중복을 찾을 수 있었습니다. 두 단계로 갔습니다. 먼저 CSV에서 크기와 파일명이 함께 일치하는 그룹만 뽑고, 그렇게 좁힌 후보에만 SHA-256 해시를 걸어 바이트 단위로 같은지 확인했습니다. 96만 개 전부에 해시를 거는 건 시간이 감당이 안 됩니다.

1차 후보는 41,388그룹, 잠재 회수량 554.5GB였습니다. 여기서 실제 해시 검증에 들어갔는데, 이게 생각보다 훨씬 오래 걸렸습니다. 4시간이 지난 시점의 진행률이 10,000/41,388이었습니다. 다만 큰 파일부터 처리하도록 정렬해둔 덕에 뒷부분은 훨씬 빨리 빠졌습니다. 뒤로 갈수록 가벼웠습니다.

최종 검증 결과는 547.8GB, 41,095그룹, 오류 0건이었습니다. 중복이 어디에 있었는지가 뜻밖이었습니다.

위치여분 용량
931GB 드라이브 내부 자체 중복245.9GB
외장 2TB 내부 자체 중복116.8GB
두 드라이브 간 교차 중복60.2GB
회사 공유 드라이브와 클라우드 미러 간 교차38.3GB
공유 드라이브 내부34.1GB
USB와 외장 간12.0GB

가장 컸던 245.9GB가 드라이브 하나 안에서의 자체 중복이었습니다. 다른 드라이브와 겹친 게 아닙니다. 한 드라이브 안에서 같은 파일이 폴더 이름만 바꿔가며 여러 벌 존재했다는 뜻입니다. 몇 년 치 백업 폴더가 쌓이면 이렇게 됩니다. 남 얘기가 아닙니다.

지우기 전에 드라이런을 돌렸습니다

드라이브 내부 완전중복 삭제 대상은 14,988건이었습니다. 바로 실행하지 않았습니다. 삭제 예정 목록 전건을 로그로 먼저 뽑아 눈으로 확인한 뒤에 실행했습니다. 여기에 안전장치를 하나 더 걸었습니다. 삭제 직전에 파일 크기를 한 번 더 확인해서, 스캔을 마친 뒤에 내용이 바뀐 파일이라면 그냥 건너뛰고 넘어가게 만들었습니다.

실제 결과는 14,955개, 152.6GB 회수였습니다. 대상 14,988건 중 33건을 건너뛴 셈입니다. 안전장치가 실제로 작동한 흔적입니다.

첫 스캔은 파일명 하나 때문에 통째로 주저앉았습니다
삭제보다 목록이 먼저였고, 그 목록을 만드는 데서부터 걸렸습니다.

USB 비우기에서 낸 사고

32GB USB를 이동용으로 돌리려고 내용물을 전부 비웠습니다. 외장하드에 같은 파일이 이미 있는 건 지우고, 나머지는 외장 아카이브 폴더로 복사한 다음 해시 검증까지 마치고서 원본을 지웠습니다. 9,573개를 처리했습니다. 사용량은 0.1GB로 떨어졌습니다.

여기서 두 가지가 걸렸습니다. 하나는 사고였습니다.

첫째, 파일 하나가 끝내 옮겨지지 않았습니다. CAD 폰트 파일이었는데 복사 자체가 OSError로 실패했습니다. 읽기 자체가 안 되는 손상 파일이었고, USB 파일 시스템이 망가진 자리로 보였습니다. 무리한 재시도는 하지 않고 보류해뒀다가, 어차피 이 USB는 포맷할 예정이었으므로 그대로 두고 끝냈습니다.

둘째가 진짜 실수였습니다. USB 루트에 있던 공인인증서 폴더까지 통째로 아카이브로 옮겨버렸습니다. 며칠 뒤에 알았습니다. 은행 사이트에 들어갔는데 인증서 목록이 비어 있었습니다. 은행이나 세무 사이트는 인증서를 USB 루트의 `NPKI\` 폴더에서만 찾기 때문에, 내용이 멀쩡해도 폴더를 다른 데로 옮기는 순간 목록에서 사라집니다. 아카이브에 사본이 남아 있었으므로 원위치로 복원해서 해결했습니다. 다만 이건 “중복이니까 옮겨도 된다”는 판단이 통하지 않는 예외였습니다. 파일 내용이 같아도 위치 자체가 기능인 파일이 있습니다. 인증서가 그렇습니다.

931GB 드라이브를 통째로 비운 밤

스캔 결과 이 드라이브의 정체가 드러났습니다. 창고였습니다. 912GB 중 99%가 5년 이상 손대지 않은 파일이었습니다. 예전 직장 시절 자료를 옛 드라이브에서 통째로 복사해둔 사본이었고, 그 뒤로 아무도 열어보지 않은 채 그대로 굳어 있었습니다. 수정 연령 분포가 극단적입니다.

  • 1년 이내: 0.0GB (28개)
  • 1~3년: 7.2GB
  • 3~5년: 1.3GB
  • 5년 초과: 903.8GB (520,278개)

5년 넘은 파일이 903.8GB입니다. 사실상 전부입니다. 5년 동안 읽기만 하고 아무것도 쓰지 않은 창고였습니다.

내용을 다 버리는 대신 외장 아카이브로 통째로 흡수시키고, 드라이브 자체는 포맷해서 백업 전용으로 바꾸기로 했습니다. 스크립트를 4단계로 짜서 밤새 돌렸습니다.

  1. 다른 드라이브에 사본이 확인된 중복 삭제
  2. 과거에 이미 중복 판정해둔 옛 휴지통 폴더 삭제
  3. 잔여 전량을 외장으로 복사 후 해시 대조 후 원본 삭제
  4. 잔여 집계

9시간을 돌린 시점의 중간 결과는 이랬습니다.

  • 1단계 중복 삭제: 24,273개 / 38.4GB
  • 2단계 옛 휴지통: 101,915개 / 28.3GB
  • 3단계 이관: 20만 개 / 441GB, 잔여 약 130GB

최종적으로 3단계 이관은 378,084개, 581.2GB, 오류 0으로 끝났습니다. 처리 속도는 로그 기준으로 시간당 약 56GB였습니다. 이 숫자가 나오고 나서야 남은 물량으로 잔여 시간을 계산할 수 있었습니다. “언제 끝나냐”는 질문에 대략 2시간 30분 같은 답을 낼 수 있게 된 것도 그 덕분입니다.

작업 중간에 프로그램이 한 번 꺼졌습니다. 그때도 손실은 없었습니다. 이미 지운 파일은 “이미 없음”으로 빠르게 건너뛰고 중단된 지점부터 그대로 이어졌기 때문입니다. 복사와 검증을 먼저 하고 삭제를 나중에 하는 순서가 여기서 제값을 했습니다.

포맷은 결국 손으로 했습니다

잔여 0개를 실측으로 확인한 뒤 포맷을 시도했습니다. 여기서 막혔습니다. 빠른 포맷 명령은 관리자 권한 부족과 다른 프로세스의 드라이브 점유로 거부됐고, 권한 승격 창을 띄우려던 시도마저 응답 시간 초과로 차단됐습니다. 결국 탐색기에서 드라이브를 우클릭해 직접 포맷했습니다. 30초 만에 끝났습니다.

자동화가 끝까지 가지 못하는 지점이 있습니다. 권한 승격이 그중 하나입니다.

그 외에 실제로 걸렸던 것들

읽기 전용 속성. 오래된 설치파일 폴더를 지우다가 `WinError 5`로 멈췄습니다. 읽기 전용 속성이 걸린 파일에서 멈춘 것이고, 그 바람에 폴더가 절반만 지워진 애매한 상태로 남았습니다. 속성을 해제하고 다시 삭제해서 마무리했습니다. 오래된 미디어 파일 몇 개도 같은 이유로 한 번에 지워지지 않아, 똑같이 속성을 푼 뒤에 다시 지웠습니다.

열려 있는 파일. 엑셀 파일 하나가 이동에 실패했습니다. 어딘가에서 열려 있어서 잠금 파일(`~$`로 시작하는 파일)이 남아 있었기 때문입니다. 엑셀을 닫으니 옮겨졌습니다.

클라우드 연동 드라이브. 30GB짜리 개인 드라이브에서 11GB를 정리했습니다. 그런데 여유 공간이 전혀 늘지 않았습니다. 이 드라이브가 클라우드 서비스와 연동된 볼륨이라, 탐색기에서 지운 파일이 클라우드 쪽 휴지통에 고스란히 남아 자리를 차지하고 있었던 것입니다. 웹에 들어가 휴지통을 비우고 나서야 사용량이 21.4GB에서 9.8GB로 떨어졌습니다. 그리고 그 서비스의 시스템 폴더는 앱이 잡고 있어서 이동 자체가 거부됐습니다. 이런 폴더는 안 건드리는 게 맞습니다. 그대로 뒀습니다.

승인 대기의 타임아웃. 삭제나 포맷처럼 되돌릴 수 없는 명령은 실행 전에 반드시 저한테 확인을 받도록 걸어뒀습니다. 그런데 자리를 비운 사이에 확인 창이 응답 없이 타임아웃돼 작업이 두 번 멈춰 섰습니다. 화면만 보고 앉아 있을 수는 없으니, 확인이 필요한 시점에 휴대폰으로 알림이 오게 바꿨습니다. 이후로는 자리에 없어도 작업이 멈춰 있는 시간이 줄었습니다.

가장 큰 중복 덩어리는 드라이브 한 대 안에 있었습니다
다른 드라이브와 겹친 게 아니라 같은 파일이 폴더만 바꿔가며 여러 벌 있었습니다.

무엇을 지웠고 무엇을 안 지웠는지

정리를 마치고 스스로 확인한 게 이 구분이었습니다. 지운 건 세 종류뿐입니다.

  1. 해시로 바이트 단위까지 같다는 게 검증된 완전 중복 약 203GB. 원본 1부는 빠짐없이 전부 남겼습니다.
  2. 제가 직접 지우기로 정한 오래된 영상 파일 45.7GB. 2019년 노트북 백업에 7년째 묻혀 있던 다큐멘터리류였고, 지금은 굳이 갖고 있지 않아도 스트리밍으로 언제든 볼 수 있는 것들입니다.
  3. 과거에 이미 중복 판정해뒀던 옛 휴지통 폴더 28.3GB.

여기에 판단이 필요했던 두 건이 더 붙습니다. 10년 넘은 구식 소프트웨어 설치파일 24.1GB는 지웠고, 지금도 쓰는 설계 툴 설치파일은 남겼습니다. 예전 직장 메일 백업 파일도 나눠서 처리했습니다. 제 것이 아닌 남의 메일 백업 27.9GB는 지웠습니다. 제 이력에 해당하는 46GB짜리는 남겼습니다.

그 외에는 한 파일도 지우지 않았습니다. 5년 넘은 자료든 뭐든 내용이 마음에 안 들어서 버린 건 하나도 없습니다. 전부 이동이었습니다. 지금은 “쓰레기는 버리고 짐은 창고에 넣은” 단계입니다. “이게 아직 필요한가”라는 가치 판단은 아직 하지 않았습니다. 그 판단은 뒤로 미뤘습니다.

정리 후의 배치

역할은 하나씩만 줬습니다.

  • 회사 공유 드라이브: 살아 있는 작업만. 342GB, 여유 236GB
  • 2TB 외장: 아카이브 본체. 여기에만 있는 자료, 즉 원본의 은퇴처
  • 931GB 내장: 포맷 후 백업 전용. 원본이 아니라 사본만 받는 곳
  • 32GB USB: 상주 데이터 없음. 이동용, 그리고 인증서 자리
  • 30GB 개인 드라이브: 현역 개인 작업물만

핵심은 외장과 백업 드라이브의 성격 차이입니다. 외장은 “여기 없으면 사라지는 것”입니다. 백업 드라이브는 “날아가도 원본이 살아 있는 것”입니다. 이 구분을 흐리면 백업이 아닙니다. 그냥 또 하나의 창고가 됩니다.

외장하드 루트도 손봤습니다. 전에는 폴더 19개가 아무 층 없이 평면으로 깔려 있었습니다. 예전 직장 프로젝트, 개인 자료, 옛 PC 백업, 정체를 알 수 없는 폴더가 아무 규칙 없이 뒤섞인 상태였습니다. 이걸 회사 아카이브, 이전 직장 자료, 개인 아카이브, PC 백업, 미정리 다섯 구역으로 재편했습니다. 같은 디스크 안에서의 이름 변경이라 실행 자체는 순식간에 끝났습니다.

개인 드라이브는 개인과 업무로 먼저 2분할하고, 그 아래에 목적별 폴더를 뒀습니다. 루트를 열었을 때 폴더가 세 개만 보이게 하는 게 목표였습니다. 낱개 파일이 루트에 굴러다니지 않도록, 파일 하나하나에 전부 소속을 줬습니다.

여기서 얻은 기준

폴더 구조의 정답 기준은 하나로 정리됩니다. 검색 없이 폴더 이름만 따라가다 보면 원하는 파일이 나오는 것. 그게 되면 잘 짠 구조입니다. 안 되면 이름을 잘못 붙인 것입니다.

작업 방식에서 남은 것도 하나입니다. 순서입니다. 지우는 동작은 전부 “복사, 검증, 그다음 삭제” 순서로 고정했습니다. 애매한 것은 그 자리에서 판단하지 않고 보류 목록에 쌓아뒀다가, 작업이 끝난 뒤에 한 번에 몰아서 결정했습니다. 이틀 동안 스크립트가 죽고, 프로그램이 꺼지고, 권한에 막히고, 파일이 잠겨 있는 일까지 다 겪었는데도 결국 잃은 게 없었던 이유가 이 두 가지입니다.

물론 다음 과제는 남아 있습니다. 시스템 드라이브 여유는 12.9GB로 여전히 빠듯합니다. 회사 공유 드라이브의 폴더 체계는 아직 손도 대지 않았습니다. 아카이브에 넣은 자료 중 다시 볼 일이 없는 덩어리를 실제로 버릴지도 결정하지 않았습니다. 정리는 한 번에 끝나지 않습니다. 이번 몫은 지도를 만들고 짐을 옮기는 데까지였습니다.

책상 노트 운영자
함께 보면 좋은 글
error: Content is protected !!