ファイル 重複 削除 フリーソフトの前に確かめる3つのこと

ディスクの空きが減ってきたので、ファイル 重複 削除 フリーソフトを探して走らせた。40GB分の重複が見つかったと出たので消した。ところが空き容量はほとんど変わらなかった。Macではこれがかなりの頻度で起きる。原因は道具の性能ではなく、APFSというファイルシステムが同じ中身を2回数えられる形で持てることにある。先に仕組みを押さえておけば、どのフリーソフトを選ぶかより手前で判断が付く。

消しても空きが増えない理由

macOS 26.6.2 の実機で、800MBのファイルを使って測った結果を示す。空き容量は df で毎回読み直している。

複製する前の空き : 269935MB
cp -c のあとの空き: 269939MB (差 -3MB)
cp のあとの空き   : 269139MB (差 799MB)

cp -c はクローンを作る。どちらかに書き込みが起きるまで同じブロックを指し続けるので、容量をまったく使わない。ふつうの cp は 799MB を丸ごと使った。ここまでは想像どおりになる。問題は同じフォルダを du で測ったときで、こう出る。

$ du -sh big2
2.3G	big2

800MBのファイルが3本で 2.3GB という計算になっている。クローンは容量を使っていないのに、大きさとしては満額で数えられているということになる。ファイルの側から見れば、そのバイト列は確かにそこにあるためになる。だからファイルサイズや中身のハッシュで重複を探す道具は、例外なくクローンを重複として拾う。そして消しても空きは1バイトも増えない。

クローンは特殊な操作の産物ではない。Finderで項目を複製したとき、同じボリューム内でコピーしたとき、バックアップや素材管理の道具が内部で使ったときに、静かに増えていく。数年使ったMacなら相当な数が溜まっている。報告された重複の量に対して回収できた空きが極端に少ないなら、まずこれを疑う。スキャン側の設定をどう変えても結果は変わらない。

無料の道具それぞれの現在地

名前だけが記事に残り、開発が止まったあとも勧められ続ける道具がある。Homebrewと各プロジェクトの公開情報で、今の状態を確かめた。

道具 費用 ライセンス 最新リリース Macでの入手
jdupes 無料 MIT 1.31.1 Homebrew。macOS 26のApple silicon向けビルド有り
fdupes 無料 記載なし 2.4.0 Homebrew
rmlint 無料 GPL-3.0-or-later 2.10.3 Homebrew。macOS 26のApple silicon向けビルド有り
dupeGuru 無料 GPL-3.0 4.3.1(2022年7月9日公開) 公式サイトに macOS (10.12+) 版
Czkawka 無料 オープンソース 12.0.1(2026年7月29日公開) 配布されているMac版はarm64のみ

読み方に注意が要るのは下の2つになる。

dupeGuru はリポジトリが止まっているわけではなく、2026年1月6日にもコミットが入っていて、アーカイブもされていない。止まっているのはリリースのほうで、タグの付いた最新版は2022年7月の 4.3.1 のままになる。公式サイトが配っているMac版の表記は macOS (10.12+) で、以降のmacOSの変化やApple siliconへの移行より前のビルドということになる。避ける理由ではないが、時間を使う前に知っておく話になる。日本語の読者にはもう1つ関係する事実がある。公式サイトの対応言語の記載はこうなっている。

Supported languages: English, French, German, Chinese (Simplified), Czech, Italian, Armenian, Russian, Ukrainian, Brazilian, Vietnamese. 出典: dupeguru.voltaicideas.net

日本語は入っていない。削除の可否を決める画面を英語で読むことになるので、その前提で選ぶ必要がある。

Czkawka は逆で、2026年7月に 12.0.1 が出ている。ただし配布されているMac向けのファイル名にはすべて arm64 が入っており、Intel Mac向けのビルドはリリースに含まれていない。Intel Macなら自分で組み立てることになる。

いちばん地味なのがコマンドの2つで、驚きが少ないのもここになる。jdupes と rmlint はどちらも macOS 26 のApple silicon向けのビルド済みパッケージがHomebrewにあるので、導入は待つだけで終わる。

何も入れずに現状を測る

道具を選ぶ前に、どれくらい重複があるのかは手元のコマンドだけで分かる。大きさが違うファイルは重複になり得ないので、まず大きさでふるいにかける。残ったものだけハッシュを取ればよい。

$ find 対象 -type f -exec stat -f "%z %N" {} \; | sort -n

1回しか出てこない大きさは、その時点で終わりになる。残りを並べて突き合わせる。

find 対象 -type f -print0 | xargs -0 shasum -a 256 | sort > /tmp/h.txt
awk '{h=$1; $1=""; sub(/^ +/,""); if (h==p) print "DUP: " prev " <-> " $0; p=h; prev=$0}' /tmp/h.txt

小さな試験用のフォルダで実際に走らせると、中身が同じ組をすべて出した。cp -c で作ったクローンも同じように出た。ここが大事なところになる。この手順もクローンと本物の複製を区別できない。中身のレベルでは同じものなので当然になる。それでも意味があるのは、消す前に人の目で見られる長さの一覧が手に入るためになる。進捗バーと合計値だけを見せる画面よりは判断ができる。

重複を探す前に、容量がどこへ行ったかを見る

重複の削除は、取り返せる容量としてはたいてい最大ではない。1つのフォルダが問題のほとんどを占めているのに、重複探しに一晩使ってしまうことがよく起きる。上の階層を大きさ順に並べるのは1行で済む。

$ du -d 1 -h ~/work | sort -hr | head -5
 11G	/Users/admin/work
3.2G	/Users/admin/work/tmp
3.2G	/Users/admin/work/scripts
2.9G	/Users/admin/work/backups
1.7G	/Users/admin/work/.git

いちばん大きいものへ1階層ずつ降りていけば、実際の重さがどこにあるかは1分もかからずに分かる。そして出てくる答えは、重複探しの道具では絶対に挙がらないものであることが多い。ビルドの中間物、依存パッケージのフォルダ、仮想マシンのイメージ、古い書き出し、リポジトリの履歴などになる。どれも重複ではない。どれも取り返せる容量で、しかも道具が選んだファイルを消すよりはるかに危険が少ない。

先にこれをやっておくと、あとで走らせる重複スキャンの数字も読めるようになる。上の階層が200GBあって重複が40GBと出たなら、調べる価値がある。木全体で20GBしかないのに重複が40GBと出たなら、どこかで二重に数えている。真っ先に疑うのがクローンになる。

走らせてはいけない場所が3つある

写真のライブラリ

~/Pictures/Photos Library.photoslibrary はパッケージで、Finderには1つの項目に見えるが、中身は元データと書き出し済みの画像とデータベースが入った木になる。中身で判定する道具は、元データと書き出しを別々のファイルとして見て、本当にバイト単位で同じものを見つけて削除を提案してくる。消されたほうをデータベースは指し続ける。写真の重複は写真アプリ自身の重複表示から扱うもので、ファイル走査の道具の仕事ではない。

まだ手元に落ちていないファイル

iCloud Driveでストレージを最適化していると、ファイルは名前だけあって中身が手元に無い状態になり得る。ls のマニュアルには -% という指定があり、そうしたファイルを見分けること、そしてディレクトリを実体化させずに済ませることが書かれている。裏を返せば、ふつうにたどると実体化する。重複スキャンをiCloudのフォルダに向けると、歩いた先を片端から静かにダウンロードし、落としたばかりのものをハッシュしていくことになる。

アプリの中と依存パッケージ

アプリケーションの中身や node_modules は、同じ小さいファイルが大量に並ぶように作られている。走らせれば何千件も見つかるが、消せば動かなくなる。最初のスキャンより前に除外に入れておくもので、失敗したあとに入れるものではない。

どちらが元なのかを決める

本物の重複だと分かったあと、どちらを残すかを決めることになる。真っ先に思い付くのは更新日だが、これが当てにならない。コピーが日付を壊すためになる。

$ touch -t 202001010000 orig.bin
$ cp orig.bin plain.bin ; cp -p orig.bin preserved.bin
2020年1月1日 00:00:00  orig.bin
2026年9月5日 13:41:19  plain.bin
2020年1月1日 00:00:00  preserved.bin

ふつうの cp はコピー側に現在時刻を刻む。つまり新しく見えるほうがコピーで、古く見えるほうが元ということが頻繁に起きる。cp -pmv は日付を保つので、フォルダに並んだ日付は「いつ書かれたか」ではなく「どうやって来たか」を表していることになる。日付より、置かれている階層の深さ、フォルダの名前、そのファイルを参照しているものがあるかどうかのほうが判断材料になる。

消したあとの空きにも間があく。ゴミ箱を空にするまでファイルは残るし、Time Machineのローカルスナップショットが削除前のブロックを保持していることもある。手元にあるかどうかは tmutil listlocalsnapshots / で一覧できる。片付けた直後に測った空き容量は、実際に回収できた量より小さく出ることがある。

道具に決められないこと

バイト単位で同じかどうかは事実になる。要らないかどうかは判断で、道具はそこには踏み込まない。重複として挙がってくるが、たいていはそのまま置いておくべきものが3種類ある。

意図して置いた複製がその1つになる。案件のフォルダと保管用のフォルダに同じ書類があるとき、それぞれの場所で役目を持っている。片方を整理しても失わないように、わざと2つ置いてある。道具には無駄に見えるが、置いた人には保険になる。

書き出したファイルがその2つ目になる。同じ書類を編集せずに2回PDFにすれば、名前も日付も違う同一の中身が2本できる。どちらを後続の仕組みが参照しているかは、ファイルシステムからは見えない。要らなさそうに見えるほうを消すと、それを指していた何かが壊れる。

バージョン管理の中のファイルがその3つ目になる。枝や作業ツリーや同梱された依存関係のあいだで同じファイルが並ぶのは、そうあるべき状態になる。片方を消すと、その仕組みが作った覚えのない状態になり、説明も付かなくなる。

進め方を決めておけば3つとも避けられる。ホームフォルダ全体に道具を向けるのではなく、1つのフォルダずつ扱う。大きい候補から始める。小さい組を100個片付けても、1回の誤削除に見合わないためになる。確定した重複は消さずに保留用のフォルダへ移し、そのまま1週間動かしてみて、何も壊れなければ保留ごと消す。この最後の一手は1週間分の容量と引き換えに、取り返しの付かない失敗という種類の事故そのものを消す。

手元の道具の配置から見えること

ここまでの判断は、どれも一覧を見ながらコマンドを打つ形になっている。大きさで絞るのはコマンド、残った組を見比べるのはフォルダ、消すかどうかを決めるのはまたフォルダになる。窓を行き来する回数が増えるほど、除外の設定を入れ忘れたり、日付だけを見て決めたりする確率が上がる。

フォルダとターミナルとAIが同じ窓にある状態なら、候補の一覧を見ながらその場でハッシュを取り直し、どちらが参照されているかを調べてから消せる。何ができるのかはできることに、ほかのファイル管理との違いは他のファイル管理との比較に、導入前に出やすい疑問はよくある質問にまとめてある。

道具を入れるかどうかより先に、報告された重複のうちどれだけがクローンなのかを見ておくほうが効く。そこが大きければ、どのフリーソフトを選んでも結果は変わらない。

よくある質問

重複を消したのに空き容量が増えないのはなぜですか?

報告された重複にAPFSのクローンが混ざっている可能性が高い。クローンは元のファイルとブロックを共有していて追加の容量を使っていないが、du にもハッシュで判定する道具にも満額の大きさとして見える。macOS 26.6.2 の実測では、800MBのファイルを複製しても空き容量は減らず、それでも du は800MBとして数えた。

無料のソフトで足りますか、有料のものが必要ですか?

中身が完全に同じファイルを探す用途なら、無料で不足はない。jdupes と rmlint はどちらも無料で、macOS 26のApple silicon向けのビルド済みパッケージがHomebrewにあり、完全一致の判定は問題なくこなす。有料の製品が売っているのは、写真や音楽の「似ているだけ」の判定と、確認しやすい画面になる。手元にあるのが完全一致か近い程度かで、払う価値が決まる。

写真のライブラリの中の重複は消してよいですか?

消さないほうがよい。ライブラリはパッケージで、中のファイルをすべて管理しているデータベースが入っている。ファイル走査の道具には、どの項目がデータベースから参照されているか分からない。中で消すとライブラリの整合が崩れる。写真アプリに重複を扱う画面があるので、そちらから行う。

重複スキャンでiCloudから勝手にダウンロードが始まりますか?

起こり得る。iCloudにしか実体が無いファイルは名前だけの状態で置かれていて、フォルダをたどると実体化する。ls のマニュアルに -% という見分けるための指定があるのは、ふつうにたどると実体化してしまうためになる。iCloudのフォルダを除外するか、先に意図してダウンロードしてから走らせれば避けられる。

記事一覧へ戻る