Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Копирование только измененных файлов + контрольная сумма (http://forum.oszone.net/showthread.php?t=353825)

Skylear 12-07-2023 18:06 3012185

Копирование только измененных файлов + контрольная сумма
 
Доброго всем времени суток. Помогите с написанием скрипта, так как нужные (для задачи) команды на просторах интернета не нашел.
Задача такова:
Есть папка "SHARE" и папка "SHARE-ARC".
Папка "SAHRE" - постоянно каждый день наполняется данными, изменяется. Соответственно папка "SHARE-ARC" - это ее копия, и сервер каждый вечер должен брать все измененные файлы из "SAHRE" и копировать в "SHARE-ARC".
Загвоздка вот в чем. Если в папке "SAHRE" какой-то файл изменился, но имя осталось прежним - он должен копироваться в папку "SHARE-ARC" рядом со своим первым файлом под именем .....(1). А файлы, которые один в один соответствуют - не копировать, дабы не занимать на это время и ресурсы. Файлы которые в структуре появились новые - копировать. Такое инкрементное копирование получается, но с дополнительным содержанием измененных файлов.
xcopy полагаю тут не очень поможет...

Skylear 12-07-2023 19:12 3012191

Полагаю вот такой вариант решает проблему частично. Пропускает файлы, если они не изменены, и заменяет, если были изменены.
А нужно создавать рядом, если были изменены. Такого что-то не найду в синтаксисе...

Код:

robocopy "E:\SHARE" "F:\SHARE-ARC" /E /R:3 /W:5 /V /NP /Z /ZB /LOG:C:\Users\adm777\Desktop\robocopy.log /XD "_АРХИВ ЗАКАЗОВ" "_ХРАНИЛИЩЕ ФАЙЛОВ" "333"

megaloman 12-07-2023 23:13 3012204

Код:

@Echo Off &Cls
        Set "DirIn=Z:\SAHRE"
        Set "DirOut=Z:\SHARE-ARC"

        For /F "usebackq delims=" %%f In (`2^>nul xcopy /D /Y /L "%DirIn%\*.*" "%DirOut%\"`) Do (
                If Exist "%%f" (
                        If Not Exist "%DirOut%\%%~nxf" (
                                >nul copy "%DirIn%\%%~nxf" "%DirOut%\"
                        ) Else (
                                Call :CopyNum "%%f"
                        )
                )
        )
Exit /B 0

:CopyNum
        Set /A i=1
        :Begin
                Set "Add=(%i%)"
                If Not Exist "%DirOut%\%~n1%Add%%~x1" (>nul Copy %1 "%DirOut%\%~n1%Add%%~x1" &Exit /B)
                Set /A i+=1
        GoTo :Begin
Exit /B


Skylear 13-07-2023 17:30 3012245

Проверил. Батник не отрабатывает. Может где-то ошибка((( окно быстро пропадает, пробовал и от админа и просто

megaloman 13-07-2023 19:19 3012249

Цитата:

Цитата Skylear
Батник не отрабатывает. Может где-то ошибка((( окно быстро пропадает »

Скорее всего, у Вас неверно указан путь. Но загвоздка еще в другом:
Цитата:

Цитата Skylear
он должен копироваться в папку "SHARE-ARC" рядом со своим первым файлом под именем .....(1). А файлы, которые один в один соответствуют - не копировать »

При такой постановке придётся для каждого файла искать его последний номер и сравнивать время каждого файла с имеющимся в архиве. Поэтому нужен другой подход: самый свежий файл должен быть без номера, самый старый - c номером (1)
Код:

@Echo Off &rem Cls
        Set "DirIn=\\192.168.100.23\Test1"
        Set "DirOut=\\192.168.100.23\Test2"

        If Not Exist "%DirIn%\" (Echo !!! Folder "%DirIn%" not found &Pause &Exit /B 2)
        If Not Exist "%DirOut%\" (Echo !!! Folder "%DirOut%" not found &Pause &Exit /B 2)

        For /F "usebackq delims=" %%f In (`2^>nul xcopy /D /Y /L "%DirIn%\*.*" "%DirOut%\"`) Do (
                Echo %%f
                If Exist "%%f" (
                        If Not Exist "%DirOut%\%%~nxf" (>nul copy "%DirIn%\%%~nxf" "%DirOut%\"
                        ) Else (Call :CopyNum "%%f")
                )
        )
Exit /B 0

:CopyNum
        Set /A i=1
        :Begin
                Set "Add=(%i%)"
                If Not Exist "%DirOut%\%~n1%Add%%~x1" (
                        >nul Ren "%DirOut%\%~nx1" "%~n1%Add%%~x1"
                        >nul copy "%DirIn%\%~nx1" "%DirOut%\"
                        Exit /B
                )
                Set /A i+=1
        GoTo :Begin
Exit /B


Skylear 13-07-2023 19:33 3012250

хм.... вообще не отрабатывает((
Пути локальные, а не сетевые.

и как старый будет добавляться под номером? все время переименовываться??? не совсем понимаю.
Схема такая:

Люди работают в шаре, например, один человек сегодня сделал файл-документ, а завтра его изменил и пересохранил. Так вот зеркальная шара для этого и нужна - чтобы иметь и сегодняшний документ и вчерашний. Так как они могут отличаться.
И сервер отрабатывает скрипт - и собирает измененные файлы с первой шары во вторую, но получается должен при совпадении имени, но разной дате создания - сохранять его рядом, а старый файл со вчера уже лежит и его незачем переименовывать

megaloman 13-07-2023 19:53 3012254

Цитата:

Цитата Skylear
хм.... вообще не отрабатывает(( »

Переименуйте Ваш батник в txt и прикрепите к сообщению.
Отрабатывает, и неважно, какой путь, лишь бы реальный. Что-то Вы извратили
Берите новую версию батника, там контроль наличия путей

Цитата:

Цитата Skylear
как старый будет добавляться под номером? »

Пусть в архиве есть
file.txt
Пользователь у себя его изменил
При копировании в архив старый файл станет с номером (1) а новый сохранит имя, итого получим:
file.txt
file(1).txt
Пользователь снова изменил файл. При копировании в архив старый файл станет с номером (2) а новый сохранит имя, итого получим:
file.txt
file(1).txt
file(2).txt
Максимальный номер соответствует предпоследней версии файла
Иначе как сравнивать по датам файл у пользователя и файл в архиве, если имена будут разные. Можно сделать, но это многократно медленнее. Стандартные команды, например, xcopy, сравнивают только одноименные файлы

Skylear 19-07-2023 21:47 3012610

Вложений: 1
да, алгоритм записан верно.
батник делаю из txt, кодировка 866, акельпадом редактирую, тестировал на разных путях (в том числе с русскими символами). В батник просто нужно записать пропуск определенных папок еще, я изначально делал на robocopy (там есть пропуск папок).

скрипт на robocopy такой (тоже 866):

Код:

robocopy "E:\SHARE" "F:\SHARE-ARC" /E /R:3 /W:5 /V /NP /Z /ZB /LOG:C:\Users\Сисадмин\Desktop\robocopy.log /XD "_АРХИВ ЗАКАЗОВ" "_ХРАНИЛИЩЕ ФАЙЛОВ" "333"
файлик также прикладываю

Skylear 31-07-2023 22:14 3013167

Ребята, нет ни у кого идей?

megaloman 01-08-2023 07:03 3013172

Вложений: 1
Skylear, Обратите внимание на положение кавычек в моём коде и в Вашем
Код:

        Set "DirIn="E:\SHARE"
Прикрепляю батник в нужной кодировке. Вы не указывали в постановке, что в исходной папке содержатся не только файлы, но и подпапки, да еще некоторые надо пропускать. Это уже несколько иная задача. Предложенный код на это не расчитан.

megaloman 01-08-2023 08:44 3013176

Вложений: 1
Вариант с подпапками и исключениями
Код:

@Echo Off &Cls
        Set "DirIn=Z:\У попа была собака"
        Set "DirOut=Z:\Поп ее любил"
        Set Exclude="\Она съела\Кусок мяса\" "\Он её убил\"

        If Not Exist "%DirIn%\" (Echo !!! Folder "%DirIn%" not found &Pause &Exit /B 2)
        Pushd "%DirOut%" ||(Echo !!! Folder "%DirOut%" not found &Pause &Exit /B 2)
                >"~~~Exclude" (For %%d In (%Exclude%) Do Echo %%~d)
                For /F "usebackq delims=" %%f In (`2^>nul xcopy /EXCLUDE:~~~Exclude /D /S /Y /L /F "%DirIn%\*.*" "%DirOut%\" ^| Find "\"`) Do (
                        Set "Out=%%f"
                        (Call Set Out=%%Out: -^> =?%%)
                        For /F "usebackq tokens=1,2 delims=?" %%i In (`Call Echo %%Out%%`) Do (
                                Echo "%%i" "%%j"
                                If Not Exist  "%%j" (>nul Xcopy /Y /F "%%i" "%%~dpj"
                                ) Else (Call :CopyNum "%%i" "%%j")
                        )
                )
                Del ~~~Exclude
        Popd
Pause
Exit /B 0

:CopyNum
        Set /A i=1
        :Begin
                Set "Add=(%i%)"
                If Not Exist "%~dpn2%Add%%~x2" (
                        >nul Ren %2 "%~n1%Add%%~x1"
                        >nul copy %1 "%~dp2"
                        Exit /B
                )
                Set /A i+=1
        GoTo :Begin
Exit /B


Skylear 01-08-2023 12:56 3013190

Проверил. Вроде отрабатывает. Единственное - это не копирует пустые каталоги. И еще можно сделать, чтобы выводил в cmd что делает? Паузу я так понимаю, можно просто закомментировать.

megaloman 01-08-2023 15:22 3013201

Вложений: 1
Цитата:

Цитата Skylear
не копирует пустые каталоги. И еще можно сделать, чтобы выводил в cmd что делает? »

Чем дальше в лес, тем толще партизаны. Структурв воспроизводится. Log-файл ведётся
Код:

@Echo Off &Cls
        Set "DirIn=Z:\У попа была собака"
        Set "DirOut=Z:\Поп ее любил"
        Set Exclude="\Она съела\Кусок мяса\" "\Он её убил\"
        Set "Log=%DirOut%\~~~%~nx0.log"

        If Not Exist "%DirIn%\" (Echo !!! Folder "%DirIn%" not found &Pause &Exit /B 2)
        Pushd "%DirOut%" ||(Echo !!! Folder "%DirOut%" not found &Pause &Exit /B 2)
                >"~~~Exclude" (For %%d In (%Exclude%) Do Echo %%~d)
                xcopy /EXCLUDE:~~~Exclude /T /E /Y "%DirIn%\*.*" "%DirOut%\"
                >>"%Log%" Echo +++ %Date% %Time%
                For /F "usebackq delims=" %%f In (`2^>nul xcopy /EXCLUDE:~~~Exclude /D /S /Y /L /F "%DirIn%\*.*" "%DirOut%\" ^| Find "\"`) Do (
                        Set "Out=%%f"
                        (Call Set Out=%%Out: -^> =?%%)
                        For /F "usebackq tokens=1,2 delims=?" %%i In (`Call Echo %%Out%%`) Do (
                                Echo "%%i" "%%j"
                                If Not Exist  "%%j" (
                                        >nul Xcopy /Y /F "%%i" "%%~dpj" &>>"%Log%" Echo    "%%i" -^> "%%~dpj"
                                ) Else (Call :CopyNum "%%i" "%%j")
                        )
                )
                Del ~~~Exclude
        Popd
Pause
Exit /B 0

:CopyNum
        Set /A i=1
        :Begin
                Set "Add=(%i%)"
                If Not Exist "%~dpn2%Add%%~x2" (
                        >nul Ren %2 "%~n1%Add%%~x1" &>>"%Log%" Echo    === %2 -^> "%~n1%Add%%~x1"
                        >nul copy %1 %2 &>>"%Log%" Echo    %1 -^> %2
                        Exit /B
                )
                Set /A i+=1
        GoTo :Begin
Exit /B



Время: 23:56.

Время: 23:56.
© OSzone.net 2001-