Скрипт поиска одинаковых файлов
Добавлено: 29 фев 2012, 12:03
Этот скрипт предназначен для поиска одинаковых файлов в заданной папке и вложенных папках. Скрипт будет полезен для наведения порядка в документах, так как находит случайно сохранённые в разные места копии одного и того же файла. Также скрипт будет полезен для выявления одинаковых файлов на файловом сервере, где пользователи любят многократно копировать одни и те же файлы.
Получив информацию о дублировании файлов, пользователь или администратор сможет проверить файлы и удалить ненужные копии, сэкономив место на дисках.
Принцип работы скрипта прост: сначала он сканирует заданную папку и составляет список файлов, затем выбирает одинаковые по размеру файлы и сравнивает их содержимое. В результате скрипт выявляет файлы с одинаковым содержимым, даже если они отличаются названием. Скрипт написан на JScript.
Сканирование и подготовка списка файлов выполняются рекурсивно через соответствующие методы File System Object.
В результате files содержит список файлов.
Теперь необходимо выбрать из списка файлы, которые имеют одинаковое содержимое. Для этого список файлов сортируется по размеру файлов:
Далее производится сравнение содержимого файлов, имеющих одинаковый размер, с помощью стандартной программы FC.
Достоинством скрипта является то, что он использует только стандартные компоненты (WSH, FC), т.е. может быть запущен на любом компьютере, не требуя установки дополнительного ПО.
Недостатком является небольшая скорость работы из-за многократных сравнений.
Также скрипт не проверяет файлы в архивах (ZIP и т.п.), что было бы полезно для выявления файлов, копии которых есть и в папках, и в архивах.
Далее приведён полный текст скрипта с некоторыми изменениями и дополнениями:
- путь для проверки берётся из первого параметра командной строки.
- добавлено ограничение на минимальный размер файла (чтобы не проверять мелкие файлы).
- сортировка списка сделана в обратном порядке (по убыванию размера файлов), чтобы вывод программы начинался с более интересных "тяжёлых" файлов; сортировку легко изменить, заменив вызов files.sort(sort_by_size_desc) на files.sort(sort_by_size_asc).
- добавлен подсчёт, сколько места в байтах занимают копии.
Этот скрипт необходимо запускать с указанием пути и с перенаправлением вывода в файл:
Получив информацию о дублировании файлов, пользователь или администратор сможет проверить файлы и удалить ненужные копии, сэкономив место на дисках.
Принцип работы скрипта прост: сначала он сканирует заданную папку и составляет список файлов, затем выбирает одинаковые по размеру файлы и сравнивает их содержимое. В результате скрипт выявляет файлы с одинаковым содержимым, даже если они отличаются названием. Скрипт написан на JScript.
Сканирование и подготовка списка файлов выполняются рекурсивно через соответствующие методы File System Object.
Код: Выделить всё
var fso = WScript.CreateObject("Scripting.FileSystemObject");
var files = new Array;
scan(path);
function scan(path) {
var folder = fso.GetFolder(path);
for(var e = new Enumerator(folder.Files); !e.atEnd(); e.moveNext())
if (e.item().Size >= min_file_size)
files.push(e.item());
for(var e = new Enumerator(folder.SubFolders); !e.atEnd(); e.moveNext())
scan(e.item().Path);
}
Теперь необходимо выбрать из списка файлы, которые имеют одинаковое содержимое. Для этого список файлов сортируется по размеру файлов:
Код: Выделить всё
function sort_by_size(a,b){
if (a.size < b.size)
return (-1);
if (a.size > b.size)
return 1;
return 0;
}
files.sort(sort_by_size);
Код: Выделить всё
while (files.length > 1) {
var count = 0;
var fc = 0;
for (var i = 1; i < files.length && files[0].Size == files[i].Size;) {
fc = shell.Run("fc /b \"" +
files[0].ParentFolder + "\\" + files[0].Name + "\" \"" +
files[i].ParentFolder + "\\" + files[i].Name + "\"",0,true);
if (fc == 0) { // файлы одинаковые
WScript.StdOut.WriteLine(files[i].ParentFolder + "\\" + files[i].Name);
files.splice(i,1);
++count;
}
else
++i;
}
if (count) { // найдены копии файла files[0]
// выводим информацию о файлах или выполняем какие-то действия...
}
files.shift();
}
Недостатком является небольшая скорость работы из-за многократных сравнений.
Также скрипт не проверяет файлы в архивах (ZIP и т.п.), что было бы полезно для выявления файлов, копии которых есть и в папках, и в архивах.
Далее приведён полный текст скрипта с некоторыми изменениями и дополнениями:
- путь для проверки берётся из первого параметра командной строки.
- добавлено ограничение на минимальный размер файла (чтобы не проверять мелкие файлы).
- сортировка списка сделана в обратном порядке (по убыванию размера файлов), чтобы вывод программы начинался с более интересных "тяжёлых" файлов; сортировку легко изменить, заменив вызов files.sort(sort_by_size_desc) на files.sort(sort_by_size_asc).
- добавлен подсчёт, сколько места в байтах занимают копии.
Код: Выделить всё
var path = WScript.Arguments(0);
var fso = WScript.CreateObject("Scripting.FileSystemObject");
var shell = WScript.CreateObject("WScript.Shell");
var min_file_size = 1024; // минимальный размер файла для проверки
var files = new Array;
WScript.StdOut.WriteLine("Поиск одинаковых файлов в " + path);
scan(path);
WScript.StdOut.WriteLine("Выбрано файлов для сравнения " + files.length);
process();
WScript.Quit(0);
function scan(path) {
var folder = fso.GetFolder(path);
for(var e = new Enumerator(folder.Files); !e.atEnd(); e.moveNext())
if (e.item().Size >= min_file_size)
files.push(e.item());
for(var e = new Enumerator(folder.SubFolders); !e.atEnd(); e.moveNext())
scan(e.item().Path);
}
// сравнивает по возрастанию размера файла
function sort_by_size_asc(a,b) {
if (a.size < b.size)
return (-1);
if (a.size > b.size)
return 1;
return 0;
}
// сравнивает по убыванию размера файла
function sort_by_size_desc(a,b) {
if (a.size > b.size)
return (-1);
if (a.size < b.size)
return 1;
return 0;
}
// обработка списка файлов
function process(){
var total_count = 0, total_bytes = 0;
files.sort(sort_by_size_desc);
while (files.length > 1) {
var count = 0;
var fc = 0;
for (var i = 1; i < files.length && files[0].Size == files[i].Size;) {
fc = shell.Run("fc /b \"" +
files[0].ParentFolder + "\\" + files[0].Name + "\" \"" +
files[i].ParentFolder + "\\" + files[i].Name + "\"",0,true);
if (fc == 0) { // файлы одинаковые
WScript.StdOut.WriteLine(files[i].ParentFolder + "\\" + files[i].Name);
files.splice(i,1);
++count;
}
else
++i;
}
if (count) { // найдены копии файла files[0]
WScript.StdOut.WriteLine(files[0].ParentFolder + "\\" + files[0].Name);
var extra_bytes = files[0].Size * count;
WScript.StdOut.WriteLine("> " + ++count + " одинаковых файлов (" +
files[0].Size + " байт в каждом, " +
extra_bytes + " байт в копиях)");
++total_count;
total_bytes += extra_bytes;
}
files.shift();
}
WScript.StdOut.WriteLine("Всего " + total_bytes + " байт в " +
total_count + " копиях файлов");
}
Код: Выделить всё
cscript.exe //nologo files.js \\fileserver\users > users_duplicates.txt