Задача:
Необходимо выполнить рекурсивное (то есть включая подпапки) сравнение файлов в заданных папках из командного файла, а затем удалить из текущий папки те фапйлы, которых нет в эталонной папке. Другими словами - нужно синхронизировать текущую папку с эталонной.
Решение:
Наполнение текущей папки из эталонной новыми файлами или файлами, измененными позже текущих не представляет проблемы. Пользуемся командой xcopy с параметром /D. А вот удалить из текущей папки файлы, которых нет в эталонной - это проблема. Её и будем решать.
Если бы нужно было просто сравнить папки, нам бы подошла утилита WinDiff.exe из пакета ресурсов Windows NT 4.0 Resource Kit. Возможно, эта утилита есть в более поздних выпусках Resource Kit, но, на всякий случай, так как пакет ресурсов Windows NT 4.0 Resource Kit в настоящее время недоступен, выкладываю ее здесь:
WinDiff работает как из интерфейса командной строки, так и из графического интерфейса. Результат работы выводит либо в свое окно, либо в файл,
например:
-- c:\soft\ConsUserData1 : c:\Soft\ConsUserData -- includes left-only,differing files
.\1cons err.txt only in c:\soft\ConsUserData1 ???????? --------
.\1cons_err.txt only in c:\soft\ConsUserData1 ???????? --------
-- 2 files listed
Но, поскольку нам необходимо работать с результатами сравнения, то проще и быстрее сделать это из командного файла:
Код: Выделить всё
@ECHO OFF
REM задаём рабочие папки
set "CurrDir=%~f1"
set "ModelDir=%~f2"
REM set "CurrDir=c:\Soft\ConsUserData1"
REM set "ModelDir=c:\Soft\ConsUserData"
set "MyDir=%~dp0"
REM Проверка существования и доступности папок
pushd "%CurrDir%" ||exit
pushd "%ModelDir%" && popd || exit
cd "%CurrDir%"
REM Удаляем из CurrDir-папки файлы, для которых нет соответствующего
REM (с таким же именем) файла в ModelDir-папке
REM Перебираем содержимое папки CurrDir и для каждого файла вызываем проверку
for /f "delims=" %%N in ('dir /b /s *') do call :check "%%N"
popd
goto :EOF
REM Проверка
:check
REM Записываем в переменную NewPath имя текущего файла из папки CurrDir
set NewPath="%~f1"
REM В строке NewPath ищем подстроку CurrDir и заменяем ее на подстроку ModelDir (см. Работа со строками в командных файлах: http://manaeff.ru/forum/viewtopic.php?p=1470#p1470)
REM Результат записываем в переменную NewPath
REM Для разворачивания значения переменной NewPath используем инструкцию «Call», иначе - командный
REM интерпретатор вместо значения переменных выдаст ее название
call set NewPath="%%NewPath:%CurrDir%=%ModelDir%%%"
REM Выполняем проверку - если в папке ModelDir нет текущего файла, то удаляем этот файл из папки CurrDir
if not exist "%NewPath%" del /F /Q %1 & echo %1>>%MyDir%\SyncRes.txt
goto :EOF
Exit
Запускаем этот батник с параметрами:
Код: Выделить всё
DelDiffFiles.bat "Текущая папка" "Эталонная папка"
Он выполнит проверку текущей папки с эталонной и удалит те файлы из текущей папки и ее подпапок, которых нет в аналогичном расположении эталонной папки. За основу батника взят код отсюда.
При передаче в качестве параметров сетевого UNC пути из другого батника, из-за использования в коде команды PUSHD, создающей временное имя диска, указывающее на сетевой ресурс, необходимо для вызова этого батника использовать следующий формат:
Код: Выделить всё
PushD "\\Server\Share\Folder 1\Folder 2\Folder 3\Folder 4\Folder 5"
Call c:\Soft\bat\DelDiffFiles.bat %CD% "C:\Soft\ConsUserData"
popd
Результаты работы батника сохраняются в файле SyncRes.txt, который создастся в папке, откуда запускали батник.
Ну а дополнить текущую папку файлами из эталонной, измененными в более позднее время или теми, которых вообще в текущей папке нет - можно просто командой xcopy, например с параметром /D. Вообще у xcopy множество параметров, с которыми можно поэкспериментировать, чтобы добиться совсем хитрых результатов.