動機
デジタルカメラやアクションカムなどの記録メディアを(USBメモリ,SDカードなど)のデータを別の大容量の外付けSSDにコピーして蓄積していたが、外付けSSDの残量が少なくなってきた。外付けSSDの中には重複したデータがあるようなので削除したい。重複したファイルが発生したのは、
- 外付けSSDにコピーしたあとに、記録メディアのコピー元のファイルを消去する前に追記したのちに、再度バックアップしてしまった。
- バックアップ作業を行ったOS環境の違いによりファイル名の大文字/小文字が変わってしまったことがあり、その際バックアップ作業済みなのかか未作業なのか誤解して2回バックアップしてしまった
といったことが原因のようだ。大文字小文字を区別せず、2つのディレクトリの内容の過不足をチェックするのは手間なので、スクリプトを書くことにした。
ファイル置き場
実行例
比較したい2つのディレクトリを引数にして実行すると、サブディレクトリごとに、ファイル、ディレクトリ、シンボリックリンク毎に
タイムスタンプとファイルサイズを比較する。同じサイズのファイルには、filecmp.cmp(..., shallow=False)
関数で比較する。
比較の結果を示す下記の記号をファイル名の前につけて表示する。
- 比較対象に同名のファイルがある場合には、タイムスタンプ(mtime)を表す記号(
>
,=
,<
)と内容の比較結果の記号(++
,--
,!=
,==
,!!
)を結合した3バイト
たとえば、===
は「タイムスタンプも内容も同じ」、>++
は「比較対象のディレクトリにある同名ファイルよりも新しくサイズも大きい」、=!=
は、「比較対象のディレクトリにある同名ファイルとタイムスタンプもファイルサイズも同じだが、中身(データ)は違う」という意味となる。シンボリックリンクの場合には、'=(空白2文字)'は「タイムスタンプもリンク先のパスも同じ」、'=!!'は「タイムスタンプは同じだがリンク先のパスが違う」という記号になる。
% ./cmp_dirtree ./data0 ./data1
### ========================================
1: ./data0
2: ./data1
### ========================================
###-----------------< M4ROOT >--------------------
1: ./data0/M4ROOT
2: ./data1/M4ROOT
### Sub directories: ---
1: =++ : 2019/02/09 12:43:35 : 952 : CLIP
2: =-- : 2019/02/09 12:43:35 : 476 : CLIP
1: === : 2019/02/09 12:43:35 : 68 : GENERAL
2: === : 2019/02/09 12:43:35 : 68 : GENERAL
(途中略)
### File lists: ---
1: >== : 2019/11/05 03:47:45 : 6148 : .DS_Store
2: <== : 2019/11/05 01:10:13 : 6148 : .DS_Store
1: >++ : 2019/11/02 19:09:34 : 5122 : MEDIAPRO.XML
2: <-- : 2019/07/01 19:07:35 : 2595 : MEDIAPRO.XML
1: >== : 2019/11/02 19:09:34 : 7 : STATUS.BIN
2: <== : 2019/07/01 19:07:35 : 7 : STATUS.BIN
###-----------------< M4ROOT/CLIP >--------------------
1: ./data0/M4ROOT/CLIP
2: ./data1/M4ROOT/CLIP
### File lists: ---
1: === : 2019/02/09 14:53:23 : 1878686635 : C0001.MP4
2: === : 2019/02/09 14:53:23 : 1878686635 : C0001.MP4
1: === : 2019/02/09 14:53:23 : 2008 : C0001M01.XML
2: === : 2019/02/09 14:53:23 : 2008 : C0001M01.XML
(途中略)
1: === : 2019/07/01 19:07:35 : 7627022896 : C0006.MP4
2: === : 2019/07/01 19:07:35 : 7627022896 : C0006.MP4
1: === : 2019/07/01 19:07:35 : 2009 : C0006M01.XML
2: === : 2019/07/01 19:07:35 : 2009 : C0006M01.XML
1: : 2019/07/28 14:15:53 : 15709053750 : C0007.MP4
2: ! : ~~
1: : 2019/07/28 14:15:53 : 2008 : C0007M01.XML
2: ! : ~~
(以下略)
比較するディレクトリ、ファイル数が多い場合には、./cmp_dirtree ./data0 ./data1 | grep -e ' .== '
といった方法でフィルタすると、容易に重複するファイルを見つけられるようになった。