ファイルの重複を調べるプログラムをPHPで書く
重複したファイルの名前をSQLiteに保存する。
ファイル名: find_duplicated_files.php
array_shift($argv);
$dirs = $argv;
$db = new SQLite3('./duplicated_files.db');
$db->exec("CREATE TABLE IF NOT EXISTS fingerprint (name VARCHAR(255), md5 CHAR(32), PRIMARY KEY(name))");
$db->exec("CREATE INDEX IF NOT EXISTS md5index on fingerprint(md5)");
if (count($dirs)>0) {
$fingerprints = array();
foreach ($dirs as $dir) {
$files = explode("\n",`find "$dir"`);
foreach ($files as $file) {
$name = "$dir/$file";
while (preg_match("|/\./|",$name)) $name = preg_replace("|/\./|",'/',$name);
if (is_file($name)) $fingerprints[md5(@file_get_contents($name))][] = $name;
}
}
foreach ($fingerprints as $md5 => $names) {
if (count($names)>1) {
foreach ($names as $name) {
$name = str_replace("'","''",$name);
$db->exec("INSERT OR REPLACE INTO fingerprint VALUES ('$name','$md5')");
}
}
}
}
$q = $db->query("SELECT * FROM fingerprint");
while ($a=$q->fetchArray(SQLITE3_ASSOC)) echo $a['md5']."\t".$a['name']."\n";
MD5を使ってファイルのフィンガープリントを得て、フィンガープリントが一致したら同じファイルとした。
心配ならばフィンガープリントにファイルサイズを追加すればいい。
使い方はコマンドラインで
php find_duplicated_files.php DIR [DIR1 [DIR2 ...]]
と入力する。
複数のディレクトリを対象にするときはディレクトリを列記する。
ディレクトリを指定せずに
php find_duplicated_files.php
と入力すれば、取得済みのデータを表示する。
2013/02/13 23:25