PDA

Показать полную графическую версию : Как вывести одинаковые по содержанию файлы из заданных директорий?


Lil Crazy
18-05-2010, 21:20
Всем привет) Собственно сабж - как вывести одинаковые по содержанию файлы из заданных директорий (возможны разные имена)?
Пока что знаю как сделать ввод нескольких директорий lдля поиска файлов:
Rem Задаём количество директорий для поиска (с проверкой на 0)
:NUM
Set /P $NUM="Input number of folders: "
Set $IDX=1& Set /A $NUM+=0
If %$NUM% EQU 0 GoTo NUM

Rem Задаём директории для поиска (с проверкой на существование этих директорий)
:DIR
Set /P $_%$IDX%="Input path to folder %$IDX% for search: "
Call Set $T=%%$_%$IDX%%%
If Exist %$T% Set /A $IDX+=1
If %$IDX% LEQ %$NUM% GoTo DIR
Помогите пожалуйста) Заранее благодарен:)

zonderz
18-05-2010, 23:58
одинаковые по содержанию файлы »

сравнивать контрольную сумму файлов или хеш
например с помощью md5

Lil Crazy
19-05-2010, 14:57
сравнивать контрольную сумму файлов или хеш
например с помощью md5 »
А как это написать в коде скрипта?

amel27
21-05-2010, 08:16
А как это написать в коде скрипта? »
вариант с использованием md5deep (http://md5deep.sourceforge.net/):

@Echo Off
SetLocal EnableExtensions EnableDelayedExpansion

:NUM
::--------------------------------
:: Количество каталогов для поиска
::--------------------------------
Set /P $NUM="Input number of folders: "
Set $IDX=1& Set /A $NUM+=0
::--------------------------------
If %$NUM% EQU 0 GoTo NUM

:DIR
::---------------------------
:: Имена каталогов для поиска
::---------------------------
Set /P $_%$IDX%="Input path to folder %$IDX% for search: "
Call Set $T=%%$_%$IDX%%%
If Exist %$T% Set /A $IDX+=1
::---------------------------
If %$IDX% LEQ %$NUM% GoTo DIR

Echo Удаление временных файлов...
2>Nul DEL /F/Q *.tmp *.~*
Echo Формирование списка файлов...
For /F "Tokens=1* Delims==" %%a In ('Set $_') Do md5deep -r "%%~b">>"%~n0.~t1"
Echo Сортировка списка...
Sort "%~n0.~t1" /O "%~n0.~t2"
Echo Группировка/обработка списков дублей...
Call :GRP_EX "%~n0.~t2" EX "%~n0.~t3"& Exit

:EX
::===================
:: Обработка списка
:: идентичных файлов
::-------------------
:: %1 - список файлов
::-------------------
Echo -----
Type "%~1"
::===================
GoTo :EOF

:GRP_EX
::====================================================
:: Обработка списка в формате: ключ значение
:: группировка строк, вывод значений во временный файл
:: с последующей передачей на обработку в процедуру.
::----------------------------------------------------
:: %1 - входной файл списка
:: %2 - имя процедуры обработки
:: %3 - имя для рабочего файла
::----------------------------------------------------
SetLocal& Set $F=& Set $A=& Echo _>>"%~1"
For /F "UseBackQ Tokens=1*" %%a In ("%~1") Do (
If Not "!$A!"=="%%~a" (If Not Defined $F (Echo %%~b>"%~3") Else (
Set $F=& Call :%~2 "%~3"& Echo %%~b>"%~3")) Else Set $F=F& Echo %%~b>>"%~3"
Set $A=%%~a)
::====================================================
EndLocal& GoTo :EOF


- имена файлов/каталогов не должны содержать символов "!"
- файлы с русскими буквами в именах обрабатываются, но отображаются знаком "?"

З.Ы. каждое ограничение можно снять ценой усложнения/замедления работы скрипта

amel27
21-05-2010, 13:22
кстати, можно и штатными средствами через FC - не самый оптимальный вариант в плане скорости, особенно при сравнении больших файлов... поэтому, только из академического интереса (блок ввода путей опустил):

@Echo Off
SetLocal EnableExtensions EnableDelayedExpansion

Set $_1=C:\TEST1
Set $_2=C:\TEST2

Echo.&<Nul Set /P $TMP="Удаление временных файлов..."
Echo Ok& 2>Nul DEL /F/Q *.tmp *.~*
<Nul Set /P $TMP="Формирование списка файлов..."
For /F "Tokens=1* Delims==" %%a In ('Set $_') Do DIR /B/A-D/S "%%~b">>"%~n0.tmp"2>Nul
Echo Ok&<Nul Set /P $TMP="Добавление размера файлов..."
For /F "UseBackQ Delims=" %%i In ("%~n0.tmp") Do Echo %%~zi,"%%~i">>"%~n0.~t1"
Echo Ok&<Nul Set /P $TMP="Сортировка списка..."
Sort "%~n0.~t1" /O "%~n0.~tmp"&& DEL "%~n0.~t1"&& REN "%~n0.~tmp" "%~n0.~t1"
Echo Ok& Echo.

Call :GRP_EX "%~n0.~t1" EX_Z "%~n0.~t2"& Exit

:EX_T
::===================
:: Обработка списка
:: идентичных файлов
::-------------------
:: %1 - список файлов
::-------------------
Echo -----
Type "%~1"
::===================
GoTo :EOF

:EX_Z
::=========================================
:: Попарное сравнение файлов одного размера
::-----------------------------------------
:: %1 - список файлов
::-----------------------------------------
SetLocal
::сохранение пар размер/файл в переменные окружения
For /F "Tokens=1* Delims=[]" %%a In ('^<"%~1" Find /N /V ""') Do Set $FZ_%%a=%%~b& Set $NZ=%%a
::попарное сравнение и формирование сигнатуры сравнения
For /L %%i In (1,1,%$NZ%) Do For /L %%j In (1,1,%$NZ%) Do (
FC /B "!$FZ_%%i!" "!$FZ_%%j!">nul& Set $MZ_%%i=!$MZ_%%i!!ERRORLEVEL!)
::сохранение/сортировка списка в формате: сигнатура,"имя файла"
For /F "Tokens=1,2* Delims==_" %%a In ('Set $MZ_') Do Echo %%c,"!$FZ_%%b!">>"%~n0.~t3"
Sort "%~n0.~t3" /O "%~n0.~tmp"&& DEL "%~n0.~t3"&& REN "%~n0.~tmp" "%~n0.~t3"
::группировка по значению сигнатуры и вызов EX_T
Call :GRP_EX "%~n0.~t3" EX_T "%~n0.~t4"& DEL /F/Q "%~n0.~t3"
::=========================================
EndLocal& GoTo :EOF

:GRP_EX
::====================================================
:: Обработка отсортированного списка: ключ,значение
:: группировка строк, вывод значений во временный файл
:: с последующей передачей на обработку в процедуру.
::----------------------------------------------------
:: %1 - входной файл списка
:: %2 - имя процедуры обработки
:: %3 - имя для рабочего файла
::----------------------------------------------------
SetLocal& Set $F=& Set $A=& Echo _>>"%~1"
For /F "UseBackQ Tokens=1* Delims=," %%a In ("%~1") Do (
If Not "!$A!"=="%%~a" (If Not Defined $F (Echo %%~b>"%~3") Else (
Set $F=& Call :%~2 "%~3"& Echo %%~b>"%~3")) Else Set $F=F& Echo.%%~b>>"%~3"
Set $A=%%~a)
::====================================================
EndLocal& GoTo :EOF

Lil Crazy
23-05-2010, 11:17
amel27, спасибо большое - использовал второй вариант.




© OSzone.net 2001-2012