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

keisersoze 24-05-2016 16:58 2637327

Файлы по маске из архивов за неделю поместить в другой архив, обозвав датой изменения
 
В течении недели в заданном каталоге формируются *.rar архивы. Нужно в момент запуска батника найти все существующие архивы за неделю из параметра (нет параметра у батника - найти за текущую неделю, параметр "-1" - за прошлую, "-2" - позапрошлую и т.д.), вытащить из найденных архивов по заданной маске/маскам файлы и запаковать в другой заданный каталог в новый архив с именем "ГГГГ.ММ.ДД - YYYY.MM.DD.rar", где "ГГГГ.ММ.ДД" - дата изменения самого свежего архива/архивов обрабатываемой недели, "YYYY.MM.DD" - дата изменения самого позднего найденного архива/архивов обрабатываемой недели.

Если за неделю отсутствуют архивы или нужные файлы по маске/маскам в них не найдены, то батник не должен создать новый архив.
Если найдены архивы с файлами только за один день или нужные файлы есть в архивах только за один день среди всех найденных архивов - имя нового архива очень желательно в виде одной даты "yyyy.mm.dd.rar".

Спасибо всем откликнувшимся.

megaloman 25-05-2016 16:35 2637573

keisersoze, не понятно, если в неделе вы каждый день запустите батник без параметра 7 раз, то получите 7 архивов с частично повторяющимися файлами и только последний архив будет полным за неделю.
Я бы предложил именовать все архивы датавоскресенья-датапонедельника в заданном вами формате, тогда запускайте батник хоть сто раз, полУчите нормальный архив в конце концов. Либо делайте архив за каждый день отдельно с именем даты.
ИМХО, самый свежий==самый поздний :)

keisersoze 25-05-2016 20:38 2637635

megaloman, Батник не будет запускаться 7 раз, однако день, когда его будет необходимо запустить и обработать указанные архивы, становится известен не заранее (обычно это пт-вс, но всякое бывает) - по почте прилетает письмо, что на этой неделе больше не будет данных. Таким образом возможен запуск для текущей недели только 1 раз и пока вручную, когда точно известно что в текущей неделе ничего не изменится.

megaloman 26-05-2016 13:34 2637793

keisersoze, Вот решение, в предположении, что в системе дата отображается в виде дд.мм.гггг. Кроме того, понедельник-1 день недели. При работе в выходной папке создаётся временная подпапка с именем ггггммдд воскресенья заданной недели, которая в конце работы батника удаляется.
Получилось громоздко из-за подсчета дат
Код:

@Echo off
cls

Set "InBox=D:\Delete\DirIn"
Set "OutBox=D:\Delete\DirOut"
Set "InMask=*.rar"
Set "OutMask=*1603*.bat"

Set "Arc=C:\Program Files\WinRAR\Rar.exe"

Set /A NWeek=0
If Not ""=="%1" Set /A NWeek=%~1

Call :DWeek17 "DWeek1" "DWeek7" %NWeek%
Echo %Date% %DOW% %DWeek1% %DWeek7%

SetLocal EnableExtensions EnableDelayedExpansion

md "%OutBox%\%DWeek7%" 2>nul
pushd "%OutBox%\%DWeek7%"
Echo -----

Set "Name1=0"
FOR /F "usebackq delims=" %%f IN (`Dir "%InBox%\%InMask%" /b /A:-D /O:-D 2^>nul`) DO (
        Call :DFile "%InBox%\%%f" "Dtt"       
        Set "Dtt=!Dtt:~6,4!!Dtt:~3,2!!Dtt:~0,2!"
        If %DWeek1% LEQ !Dtt! If !Dtt! LEQ %DWeek7% (
                If !Name1!==0 Set "Name1=!Dtt!"
                Set "Name2=!Dtt!"
                rem Echo %%f %%~tf !Dtt!
                Set Proc="%Arc%" e -y "%InBox%\%%f" "%OutMask%"
                Echo !Proc!
                !Proc! >nul 2>nul
        )
)

If Not !Name1!==0 (
        If Not !Name1!==!Name2! Set Name1=!Name1!-!Name2!
        Set Proc="%Arc%" a -df "%OutBox%\!Name1!"
        Echo +++++
        Echo !Proc!
        !Proc! >nul 2>nul
)

popd
rd /S /Q "%OutBox%\%DWeek7%"
Pause

GoTo :Eof

:DFile
        Set %~2=%~t1
GoTo :Eof

:DWeek17

Call :DayOfWeek %Date% "DOW"

Set /A Delta=1-%DOW%-7*%~3
Set "%~1=%Date:~6,4%%Date:~3,2%%Date:~0,2%"
If Not %Delta%==0 Call :FromDate %Delta% %Date% "%~1"

Set /A  Delta=7-%DOW%-7*%~3
Set "%~2=%Date:~6,4%%Date:~3,2%%Date:~0,2%"
If Not %Delta%==0 Call :FromDate %Delta% %Date% "%~2"

GoTo :Eof

:DayOfWeek

rem Выдаёт номер дня недели для даты в первом аргументе (формат дд.мм.гггг)
rem в переменную, имя которой указано во втоорм аргументе в кавычках

Set "@Date=%~1"
Set /A @YYYY=%@Date:~6,4%, @MM=1%@Date:~3,2%-100, @DD=1%@Date:~0,2%-100
Set /A %~2=((%@YYYY%-1901)*365 + (%@YYYY%-1901)/4 + %@DD% + (!(%@YYYY% %% 4))*(!((%@MM%-3)^&16))+(%@MM%-1)*30+2*(!((%@MM%-7)^&16))-1+((65611044^>^>(2*%@MM%))^&3))%%7+1

GoTo :Eof

:FromDate

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

rem Заимствовано http://forum.oszone.net/thread-186889.html
rem вызов Call :FromNow %DeltaDay% %Date% "yyyymmdd"
rem результат в перемменной %yyyymmdd%

 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 "%~3=%yyyy%%mm:~-2%%dd:~-2%"
GoTo :Eof


В предложенном решении я заимствовал 2 процедуры, их авторов указать затрудняюсь: подсчет номера дня недели и пересчёт даты на заданное количество дней.

keisersoze 27-05-2016 18:53 2638140

megaloman, а есть возможность сделать чтобы новый архив к примеру вместо 20160520-20160516.rar был 2016.05.16-2016.05.20.rar ?

megaloman 27-05-2016 20:51 2638157

Можно. Замените кусочек кода
Код:

If Not !Name1!==0 (
        Set Name1=!Name1:~0,4!.!Name1:~4,2!.!Name1:~6,2!
        Set Name2=!Name2:~0,4!.!Name2:~4,2!.!Name2:~6,2!
        If Not !Name1!==!Name2! Set Name1=!Name1!-!Name2!
        Set Proc="%Arc%" a -df "%OutBox%\!Name1!.rar"
        Echo +++++
        Echo !Proc!
        !Proc! >nul 2>nul
)


keisersoze 28-05-2016 08:36 2638231

megaloman, и еще дату "развернуть"..
можно просто заменить эту строчку
Код:

If Not !Name1!==!Name2! Set Name1=!Name1!-!Name2!
на эту
Код:

If Not !Name1!==!Name2! Set Name1=!Name2!-!Name1!
?

Подскажите еще пожалуйста, можно еще приделать, чтобы после создания архива за неделю перемещались обработанные ежедневные архивы в заданный каталог?

megaloman 28-05-2016 10:30 2638243

keisersoze, Дату Вы "разворачиваете" нормально.
Чтобы после создания архива за неделю перемещались обработанные распаковки ежедневных файлов по маске ежедневные архивы перемещались в заданный каталог допишем 2 строчки:

Set "InBox=D:\Delete\DirIn"
Set "OutBox=D:\Delete\DirOut"
Set "ArcBox=D:\Delete\DirArc"

Set Proc="%Arc%" e -y "%InBox%\%%f" "%OutMask%"
Echo !Proc!
!Proc! >nul 2>nul
Move /Y "%InBox%\%%f" "%ArcBox%\" >nul

keisersoze 28-05-2016 16:53 2638306

megaloman, тут не после создания, а после распаковки. ну и ладно, все хорошо работает, спасибо )


Время: 07:30.

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