Компьютерный форум 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=256733)

darkAge 20-03-2013 16:35 2115026

Скрипт для копирования файлов/папок с заменой
 
Всем здрасьте )) , в общем поставили передо мной такую задачу, имеется папка с бекапами, нужно что бы эта папка копировалась в определенное место, раз в сутки, а по истечении 7 дней, заменялись на новые по одному (по принципу как в видео регистраторе)
Подскажите как это реализовать, идея есть через xcopy, но она может копировать файлы по изменению в определенный день, либо после, а надо что бы более старые затирались.

darkAge 21-03-2013 10:39 2115467

megaloman, Нет, для бэкапов, каждый день создается папка, формата dd-mm-yyyy, а в неё каждый час делаются бэкапы
архивы yyyymmddhhmm.rar

darkAge 22-03-2013 14:32 2116288

Нашел вот такой скрипт

Option Explicit

Dim fso
Dim objFolder
Dim strFolder
Dim objFiles
Dim objFile
Dim datDate

On Error Resume Next

'initialize parameters
strFolder = "D:\Folder"
datDate = Now - 7 'one week ago

'set object variables
Set fso = CreateObject("Scripting.FileSystemObject")
Set objFolder = fso.GetFolder(strFolder)
Set objFiles = objFolder.Files

'loop through members of collection
For Each objFile in objFiles
'do something with file
Call DeleteOldFile(objFile, datDate)
Next

WScript.Quit Err.Number

Function DeleteOldFile(objFile, datDate)

'function deletes file which was created date specified and earlier

If objFile.DateCreated <= datDate Then
'WScript.Echo objFile.Name & " " & objFile.DateCreated
objFile.Delete
End If

End Function

но он удаляет файлы старше определенной даты

не много изменил его что бы работал с папками, а он почему то не удаляет их,


Option Explicit

Dim fso
Dim objFolder
Dim strFolder
Dim objFiles
Dim objFile
Dim datDate

On Error Resume Next

'initialize parameters
strFolder = "C:\move"
datDate = Now - 7 'one week ago

'set object variables
Set fso = CreateObject("Scripting.FileSystemObject")
Set objFolder = fso.GetFolder(strFolder)
Set objFolder = objFolder.Files

'loop through members of collection
For Each objFolder in objFolder
'do something with file
Call DeleteOldFolder(objFolder, datDate)
Next

WScript.Quit Err.Number

Function DeleteOldFolder(objFolder, datDate)

'function deletes file which was created date specified and earlier

If objFolder.DateCreated <= datDate Then
'WScript.Echo objFolder.Name & " " & objFolder.DateCreated
objFolder.Delete
End If

End Function

где я не верно делаю?

megaloman 22-03-2013 23:55 2116647

Код:

@Echo Off

Set From=D:\Delete
Set To=D:\DDDDD
Set Mask=20*.rar

Set DeltaDay=-7

rem Пересчет даты на заданное кол-во дней
rem Формат даты dd.mm.yyyy +- дни получим новые yyyymmdd

Call :FromNow %DeltaDay% %Date%
Set OldD=%yyyymmdd:~2,6%

Set InDate=%From%\%Date:~0,2%-%Date:~3,2%-%Date:~6,4%

If Not Exist "%InDate%\%Mask%" GoTo :Eof
If Not Exist "%To%\%Mask%" Copy "%InDate%\%Mask%" "%To%\" >nul

FOR /F "usebackq delims=" %%i IN (`Dir "%InDate%\%Mask%" /B /A-D /ON`) DO (
        Set Log=1

        If Not Exist "%To%\%%i" (
                FOR /F "usebackq delims=" %%j IN (`Dir "%To%\%Mask%" /B /A-D /ON`) DO Call :Nav %%i %%j
        )
)

GoTo :Eof

:Nav
        If %Log%==0 GoTo :Eof

        Set NewH=%1               
        Set NewH=%OldD%%NewH:~8,2%
        Set OldH=%2
        Set OldH=%OldH:~2,8%

        If %OldH% LEQ %NewH%  Del "%To%\%2"
        Copy "%InDate%\%1" "%To%\" >nul
        Set Log=0

GoTo :Eof

:FromNow
 SetLocal
 Set DT=%2
 Set yyyy=%DT:~-4%& set /a mm=100%DT:~3,2%%%100& set /a dd=100%DT:~,2%%%100
 Set /A JD=%~1+dd-32075+1461*(yyyy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yyyy+4900+(mm-14)/12)/100)/4
 Set /A L=JD+68569,N=4*L/146097,L=L-(146097*N+3)/4,I=4000*(L+1)/1461001
 Set /A L=L-1461*I/4+31,J=80*L/2447,K=L-2447*J/80,L=J/11
 Set /A J=J+2-12*L,I=100*(N-49)+I+L
 Set /A yyyy=I,mm=100+J,dd=100+K
 EndLocal& Set yyyymmdd=%yyyy%%mm:~-2%%dd:~-2%
GoTo :Eof

Для примера здесь в папке D:\Delete имеются подпапка с сегодняшним числом D:\Delete\22-03-2013 где хранятся файлы 20yymmddhhmm.rar
Эти файлы переписываются в D:\DDDDD, причем при записи каждого нового файла удалится старый файл, если он старше нового на неделю или более.

Пересчет даты заимствовал здесь

darkAge 23-03-2013 11:03 2116786

Спасибо, походу дела- это то что нужно.

darkAge 26-03-2013 11:31 2118757

Что-то не получается, думал что формат папки с датой не верный, я выше в примере указал dd-mm-yyyy, хотя на самом деле должно быть dd.mm.yyyy, ладно это не проблема привел папки к нужному формату, все равно не переносит,
И к стати скрипт смотрит дату создания или дату изменения файла? Я пока тестирую на другом компе, по этому перенес для проверки несколько файлов, естественно атрибуты не много изменились, дата создания отличается от даты изменения.
Системную дату поменял на месяц в перед, тоже не работает.

megaloman 26-03-2013 11:48 2118776

Цитата:

И к стати скрипт смотрит дату создания или дату изменения файла?
Цитата:

каждый день создается папка, формата dd-mm-yyyy, а в неё каждый час делаются бэкапы архивы yyyymmddhhmm.rar
Скрипт анализирует имена файлов, а не время создания/изменения. Прочел Ваше сообщение только сегодня, попробую при наличии времени вспомнить задачу и у себя восстановить контрольный пример.
Так сходу, если сегодня 26.03.2013, то у меня в примере работаем с папкой D:\Delete\26-03-2013. Если такой папки нет, или в ней нет файлов по маске 20*.rar, то скрипт ничего не делает.
В постановке задачи не указано, что батник Вы будете запускать сегодня на позавчерашние данные.
Если папка называется дд.мм.гггг, то вместо Set InDate=%From%\%Date:~0,2%-%Date:~3,2%-%Date:~6,4%
напишите
Set InDate=%From%\%Date:~0,2%.%Date:~3,2%.%Date:~6,4%
Папка D:\DDDDD тоже должна существовать (естественно, это я придумал имена, но Вы вольны придумать свои, лишь бы папки существовали, озаботьтесь, чтобы правее наименования папки в скрипте не было пробелов)
Если в папке D:\DDDDD ничего нет, перенесём туда всё содержимое папки D:\Delete\26-03-2013

darkAge 26-03-2013 13:10 2118856

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

megaloman 26-03-2013 13:47 2118879

Извольте чётко поставить задачу. Я понимал так: есть сегодняшняя папка, мы сегодня запускаем скрипт, он копирует файлы в другую папку, вытесняя при этом старые более чем недельной давности. Что хотите Вы? По какому алгоритму?
Цитата:

имеется папка с бекапами, нужно что бы эта папка копировалась в определенное место, раз в сутки
Кстати, скрипт можно запускать многократно и он корректно будет копировать файлы, но папку он определяет сегодняшнюю - Вы так просили. Не проблема сделать на любое число, но определите, что Вам нужно? Я телепатией, увы, не страдаю. :closed-to

darkAge 26-03-2013 14:13 2118902

Прошу прощения если я криво объяснил :sorry: , сам всегда требую что бы задачу ставили чётко.
Попробую как то подробней
есть папка на пример d:\bcp\ в ней папки с датой dd.mm.yyyy в этих папках архивы yyyymmddhhmm.rar.
Мне поставлена задача, что бы из папки bcp копировались файлы старше недели, задание на пример будет выполнятся раз в сутки.
то есть
01.mm.yyyy
02.mm.yyyy
03.mm.yyyy
04.mm.yyyy
05.mm.yyyy
06.mm.yyyy
07.mm.yyyy
далее проходит неделя архивы из папки 01.mm.yyyy переносятся в другую папку
ну и так раз в день, а потом соответственно в папку в которую переносятся архивы , архивы заменялись на более новые.
Что бы актуальность архивов бала 1 неделя.

Блин перечитал сам, что написал, по моему еще больше запутал.

megaloman 29-03-2013 18:13 2121650

Постановка задачи в Вашем изложении весьма запутана, поэтому сам себе ставлю задачу и сам её решаю
Имеется папка, например, E:\Delete, в которой создаются подпапки с именами вида дд.мм.гггг .
В них создаются файлы с именами вида ггггммддччмм.rar
Также есть папка, например, E:\DDDDD, в которой хранятся копии файлов из указанных папок, но копии файлов в этой папке должны храниться не более недели.
Вот батник, который удаляет в папке E:\DDDDD копии файлов старше недели (время создания файла анализируется по информации в его имени ггггммдд) и копирует все файлы в подпапках E:\Delete\дд.мм.гггг\ггггммддччмм.rar в папку E:\DDDDD, которые не старше недели и которых еще нет в папке E:\DDDDD (время создания файлов определяется из имени папки дд.мм.гггг)
Код:

@Echo Off

Set From=E:\Delete
Set To=E:\DDDDD
Set Mask=20*.rar
Set MaskD=??.??.20??

Set DeltaDay=-7

SetLocal EnableExtensions EnableDelayedExpansion

rem Пересчет даты на заданное кол-во дней
rem Формат даты dd.mm.yyyy +- дни получим новые yyyymmdd

Call :FromNow %DeltaDay% %Date%

rem Чистим папку %To% от файлов старше недели

If Exist "%To%\%Mask%" (
        FOR /F "usebackq delims=" %%j IN (`Dir "%To%\%Mask%" /B /A:-D /O:N`) DO (
                Set FDate=%%~nxj
                Set FDate=!FDate:~0,8!
                If !FDate! LEQ %yyyymmdd% (Del "%To%\%%j">NUL) Else (GoTo :Continue)
        )
)
:Continue

rem Копируем файлы из папок во %From% не старше недели

FOR /F "usebackq delims=" %%j IN (`Dir "%From%\%MaskD%" /B /A:D /O:N`) DO (
        Set FDate=%%~nxj
        Set FDate=!FDate:~6,4!!FDate:~3,2!!FDate:~0,2!
        If !FDate! GTR %yyyymmdd% XCopy "%From%\%%j\%Mask%" "%To%\" /D /Y >NUL
)

GoTo :Eof

:FromNow
 SetLocal
 Set DT=%2
 Set yyyy=%DT:~-4%& set /a mm=100%DT:~3,2%%%100& set /a dd=100%DT:~,2%%%100
 Set /A JD=%~1+dd-32075+1461*(yyyy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yyyy+4900+(mm-14)/12)/100)/4
 Set /A L=JD+68569,N=4*L/146097,L=L-(146097*N+3)/4,I=4000*(L+1)/1461001
 Set /A L=L-1461*I/4+31,J=80*L/2447,K=L-2447*J/80,L=J/11
 Set /A J=J+2-12*L,I=100*(N-49)+I+L
 Set /A yyyy=I,mm=100+J,dd=100+K
 EndLocal& Set yyyymmdd=%yyyy%%mm:~-2%%dd:~-2%
GoTo :Eof

Пересчет даты заимствовал здесь

darkAge 04-04-2013 09:21 2125473

Все верно так и должно работать, пути папок изменил на свои, имена папок в формате dd.mm.yyyy, имена архивов yyyymmddhhmm_1C.rar, но думаю это не принципиально если указана маска 20*.rar, но не копирует, просто выполняется батник, но ни чего не происходит.

darkAge 04-04-2013 11:52 2125550

Вложений: 1
Вот что происходит
Код:

C:\Documents and Settings\Администратор>D:\move\move1.cmd

C:\Documents and Settings\Администратор>chcp 866
Текущая кодовая страница: 866

C:\Documents and Settings\Администратор>chcp 1251
Текущая кодовая страница: 1251

C:\Documents and Settings\Администратор>Set From=D:\bcp

C:\Documents and Settings\Администратор>Set To=D:\target_bkp

C:\Documents and Settings\Администратор>Set Mask=20*.rar

C:\Documents and Settings\Администратор>Set MaskD=??.??.20??

C:\Documents and Settings\Администратор>Set DeltaDay=-7

C:\Documents and Settings\Администратор>SetLocal EnableExtensions EnableDelayedE
xpansion

C:\Documents and Settings\Администратор>rem Пересчет даты на заданное кол-во дне
й

C:\Documents and Settings\Администратор>rem Формат даты dd.mm.yyyy +- дни получи
м новые yyyymmdd

C:\Documents and Settings\Администратор>Call :FromNow -7 04.04.2013

C:\Documents and Settings\Администратор>SetLocal

C:\Documents and Settings\Администратор>Set DT=04.04.2013

C:\Documents and Settings\Администратор>Set yyyy=2013  & set /a mm=10004%100  &
set /a dd=10004%100

C:\Documents and Settings\Администратор>Set /A JD=-7+dd-32075+1461*(yyyy+4800+(m
m-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yyyy+4900+(mm-14)/12)/100)/4

C:\Documents and Settings\Администратор>Set /A L=JD+68569,N=4*L/146097,L=L-(1460
97*N+3)/4,I=4000*(L+1)/1461001

C:\Documents and Settings\Администратор>Set /A L=L-1461*I/4+31,J=80*L/2447,K=L-2
447*J/80,L=J/11

C:\Documents and Settings\Администратор>Set /A J=J+2-12*L,I=100*(N-49)+I+L

C:\Documents and Settings\Администратор>Set /A yyyy=I,mm=100+J,dd=100+K

C:\Documents and Settings\Администратор>EndLocal & Set yyyymmdd=20130328

C:\Documents and Settings\Администратор>GoTo :Eof

C:\Documents and Settings\Администратор>rem Чистим папку D:\target_bkp от файлов
 старше недели

C:\Documents and Settings\Администратор>If Exist "D:\target_bkp\20*.rar" (FOR /F
 "usebackq delims=" %j IN (`Dir "D:\target_bkp\20*.rar" /B /A:-D /O:N`) DO (
Echo "D:\bcp\??.??.20??" %j
 pause
 Set FDate=%~nxj
 Set FDate=!FDate:~0,8!
 If !FDate! LEQ 20130328 (Del "D:\target_bkp\%j" 1>NUL )  Else (GoTo :Continue )

) )

C:\Documents and Settings\Администратор>rem Копируем файлы из папок во D:\bcp не
 старше недели

C:\Documents and Settings\Администратор>FOR /F "usebackq delims=" %j IN (`Dir "D
:\bcp\??.??.20??" /B /A:D /O:N`) DO (
Set FDate=%~nxj
 Set FDate=!FDate:~6,4!!FDate:~3,2!!FDate:~0,2!
 If !FDate! GTR 20130328 XCopy "D:\bcp\%j\20*.rar" "D:\target_bkp\" /D /Y  1>NUL

)

C:\Documents and Settings\Администратор>(
Set FDate=06.03.2013
 Set FDate=!FDate:~6,4!!FDate:~3,2!!FDate:~0,2!
 If !FDate! GTR 20130328 XCopy "D:\bcp\06.03.2013\20*.rar" "D:\target_bkp\" /D /
Y  1>NUL
)

C:\Documents and Settings\Администратор>(
Set FDate=23.03.2013
 Set FDate=!FDate:~6,4!!FDate:~3,2!!FDate:~0,2!
 If !FDate! GTR 20130328 XCopy "D:\bcp\23.03.2013\20*.rar" "D:\target_bkp\" /D /
Y  1>NUL
)

C:\Documents and Settings\Администратор>(
Set FDate=24.03.2013
 Set FDate=!FDate:~6,4!!FDate:~3,2!!FDate:~0,2!
 If !FDate! GTR 20130328 XCopy "D:\bcp\24.03.2013\20*.rar" "D:\target_bkp\" /D /
Y  1>NUL
)

C:\Documents and Settings\Администратор>(
Set FDate=25.03.2013
 Set FDate=!FDate:~6,4!!FDate:~3,2!!FDate:~0,2!
 If !FDate! GTR 20130328 XCopy "D:\bcp\25.03.2013\20*.rar" "D:\target_bkp\" /D /
Y  1>NUL
)

C:\Documents and Settings\Администратор>GoTo :Eof


megaloman 04-04-2013 13:06 2125571

Судя по приведенному, Вам нЕчего копировать. По этой картинке будем копировать файлы из папок, начиная с 29.03.2013 и т д., а последнее, что у Вас есть, 25.03.2013 - вне диапазона на сохранение. Вы не предоставили данные для батника. Кстати, батник набран не в 866 кодировке, но, так как у Вас не присутствуют в описании путей русские буквы - это не принципиально.

darkAge 04-04-2013 17:23 2125714

Во точно, ступил, поставил 29 дней, начал копировать.
спасибо.

darkAge 28-06-2013 14:17 2175865

Вложений: 1
Здравствуйте, давно не заходил, сапасибо за помощь, но появился вопрос, где то после недели выполнения скрипта, он стал останавливаться и требует нажатия любой кнопки, как я понимаю для подтверждения удаления файла.

megaloman 28-06-2013 18:58 2176034

Безотносительно к написанным мной скриптам (сейчас некогда вспоминать и разбираться) вызываем хелп для команды Del и читаем
Цитата:

del /?
Удаление одного или нескольких файлов.

DEL [/P] [/F] [/S] [/q] [/A[[:]атрибуты]] имена
ERASE [/P] [/F] [/S] [/q] [/A[[:]атрибуты]] имена

имена Список из одного или нескольких файлов или каталогов.
Для удаления группы файлов можно использовать подстановочные
знаки. Если указан каталог, будут удалены все файлы в этом
каталоге.

/P Запрос подтверждения перед удалением каждого файла.
/F Принудительное удаление файлов, доступных только для чтения.
/S Удаление указанных файлов из всех подкаталогов.
/Q Отключение запроса на подтверждение при удалении файлов.
/A Отбор файлов для удаления по атрибутам.
атрибуты R Файлы, доступные только для чтения.
S Системные файлы.
H Скрытые файлы.
A Файлы, готовые для архивирования.
I Файлы с неиндексированным содержимым.
L Точки повторной обработки.
- Префикс "-" имеет значение НЕ.

Изменение команд DEL и ERASE при включении расширенной обработки команд:

Результаты вывода для ключа /S принимают обратный характер, то есть выводятся
только имена удаленных файлов, а не файлов, которые не удалось найти.

darkAge 01-07-2013 13:17 2177295

добавил атрибуты, не помогло все равно запрос выдается

Код:

@Echo on

chcp 866


Set From=E:\BackUp\virtual
Set To=\\192.168.3.13\Backup\Virtual
Set Mask=20*.rar
Set MaskD=??.??.20??

Set DeltaDay=-7

SetLocal EnableExtensions EnableDelayedExpansion

rem Пересчет даты на заданное кол-во дней
rem Формат даты dd.mm.yyyy +- дни получим новые yyyymmdd

Call :FromNow %DeltaDay% %Date%

rem Чистим папку %To% от файлов старше недели

If Exist "%To%\%Mask%" (
        FOR /F "usebackq delims=" %%j IN (`Dir "%To%\%Mask%" /B /A:-D /O:N`) DO (

Echo "%From%\%MaskD%" %%j
pause
                Set FDate=%%~nxj
                Set FDate=!FDate:~0,8!
                If !FDate! LEQ %yyyymmdd% (Del "%To%\%%j" /Q /F >NUL) Else (GoTo :Continue)
        )
)
:Continue


rem Копируем файлы из папок во %From% не старше недели

FOR /F "usebackq delims=" %%j IN (`Dir "%From%\%MaskD%" /B /A:D /O:N`) DO (
        Set FDate=%%~nxj
        Set FDate=!FDate:~6,4!!FDate:~3,2!!FDate:~0,2!
        If !FDate! GTR %yyyymmdd% XCopy "%From%\%%j\%Mask%" "%To%\" /D /Y >NUL
)

GoTo :Eof

:FromNow
 SetLocal
 Set DT=%2
 Set yyyy=%DT:~-4%& set /a mm=100%DT:~3,2%%%100& set /a dd=100%DT:~,2%%%100
 Set /A JD=%~1+dd-32075+1461*(yyyy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yyyy+4900+(mm-14)/12)/100)/4
 Set /A L=JD+68569,N=4*L/146097,L=L-(146097*N+3)/4,I=4000*(L+1)/1461001
 Set /A L=L-1461*I/4+31,J=80*L/2447,K=L-2447*J/80,L=J/11
 Set /A J=J+2-12*L,I=100*(N-49)+I+L
 Set /A yyyy=I,mm=100+J,dd=100+K
 EndLocal& Set yyyymmdd=%yyyy%%mm:~-2%%dd:~-2%
GoTo :Eof


sunnykey 01-07-2013 17:02 2177468

Цитата:

Цитата darkAge
добавил атрибуты, не помогло все равно запрос выдается »

У тебя в скрипте команда pause. Она вызывает остановку скрипта.
Код:

Call :FromNow %DeltaDay% %Date%

rem Чистим папку %To% от файлов старше недели

If Exist "%To%\%Mask%" (
        FOR /F "usebackq delims=" %%j IN (`Dir "%To%\%Mask%" /B /A:-D /O:N`) DO (

Echo "%From%\%MaskD%" %%j
pause
                Set FDate=%%~nxj
                Set FDate=!FDate:~0,8!
                If !FDate! LEQ %yyyymmdd% (Del "%To%\%%j" /Q /F >NUL) Else (GoTo :Continue)
        )
)

На досуге не забывай читать справку ко всем неизвестным командам
Код:

C:\>pause /?
Приостановка выполнения пакетного файла и вывод сообщения:
    Для продолжения нажмите любую клавишу . . .


darkAge 01-07-2013 18:06 2177501

Всем спасибо, все заработало.


Время: 17:07.

Время: 17:07.
© OSzone.net 2001-