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

zavoruev 02-04-2010 10:11 1383107

Перемещение устаревших файлов из папки в резервную папку
 
всем добрый день! Имеется задача перемещения устаревший файлов из папки, но не всех, а только недельной давности, что бы файлы за последнюю неделю сохранялись. Скрипт будет выполняться 2 раза в неделю. На данный момент имею вот такой скрипт, но перемещения файлов не происходит???!! Подскажите по чему!

@Echo Off
:: Параметры скрипта, 0 < $OLD < 29!
:: $OLD - столько ДНЕЙ храним архивы
Set $SRC=D:\obmen1
Set $DST=D:\Backup_Obmen1
Set $OLD=1
:: Находим текущие день/месяц/год
For /F "Tokens=1 Delims=." %%i In ('WMIC OS Get LocalDateTime^|Find "."') Do Set $Time=%%i
Set $Y=%$Time:~0,4%&Set $M=0%$Time:~4,2%&Set $D=0%$Time:~6,2%
Set $M=%$M:~-2%&Set $D=%$D:~-2%

:: копируем старые каталоги (файлы)
Call :GetOldDate %$OLD%
For /F "Tokens=1-3 Delims=." %%i In ('DIR /B/A:D %$SRC%\??.??.????') Do If %%k%%j%%i LEQ %$Y%%$M%%$D% move /Y "%$SRC%\%%i.%%j.%%k %$DST%\"
:: Выход
EXIT

:GetOldDate
:: -----------------------------------
:: Расчет даты, предшествующей текущей
:: заданное количество дней (< 29)
:: -----------------------------------
Set /A $D -= %1
If %$D% GTR 0 GoTo GetOldDate_2
:: Месяц, год, дней в месяце
Set /A $M=%$M%+11-((%$M%+10)/12)*12
If %$M% EQU 12 Set /A $Y-=1
For /F "Tokens=%$M%" %%i In ("31 28 31 30 31 30 31 31 30 31 30 31") Do Set $X=%%i
If %$M% NEQ 2 GoTo GetOldDate_1
:: Февраль високосного года
Set /A $B1=%$Y%-(%$Y%/4)*4
Set /A $B2=%$Y%-(%$Y%/100)*100
Set /A $B3=%$Y%-(%$Y%/400)*400
If 0 EQU %$B1% If 0 NEQ %$B2% Set /A $X+=1
If 0 EQU %$B3% Set /A $X+=1
:: День месяца
:GetOldDate_1
Set /A $D=%$D%+%$X%-((%$D%+%$X%-1)/%$X%)*%$X%
:: Форматирование даты
:GetOldDate_2
Set $M=0%$M%&Set $D=0%$D%
Set $M=%$M:~-2%&Set $D=%$D:~-2%
GoTo :EOF

zavoruev 05-04-2010 12:52 1385352

Товарищи)))) поготите пож-та, я знаю что ошибка у меня вот здесь
For /F "Tokens=1-3 Delims=." %%i In ('DIR /B/A:D %$SRC%\??.??.????') Do If %%k%%j%%i LEQ %$Y%%$M%%$D% move /Y "%$SRC%\%%i.%%j.%%k %$DST%\"
но т.к я не пишу скрипты не пишу, ошибку найти не могу. Жду совета или лучше всего ответа!!!

NiOl 05-04-2010 13:12 1385364

Неблагодарное занятие - копаццо в чужих скриптах (или в своих старых) - трудно разобраться.
Что сразу бросилось в глаза - в ищите только каталоги (dir /A:D), при этом команда Move может только переименовывать каталоги, но не переносить.
Что касается календаря - сам с такими вычислениями в пакетниках не разбирался, здесь мне проверять сложно.

zavoruev 05-04-2010 14:24 1385425

Цитата:

Цитата NiOl
(или в своих старых) - трудно разобраться »

вот это верно подмеченно, скрипт не мой, а Ваш! И мне бы хотелось что бы основная задача решалась, но не получается!
по этому прошу помочь в составлении нового, либо редактировании старого скрипта

На счет команды DIR, вот ключи с которыми она делается, это ни как не каталоги
/A Вывод файлов с указанными атрибутами.
атрибуты D Каталоги R Доступные только для чтения
H Скрытые файлы A Файлы для архивирования
S Системные файлы Префикс "-" имеет значение НЕ
/B Вывод только имен файлов.

И Команда Move
Перемещение одного или более файлов:
MOVE [/Y | /-Y] [диск:][путь]имя_файла1[,...] назначение

Переименование папки:
MOVE [/Y | /-Y] [диск:][путь]имя_папки новое_имя_папки

Тогда как же переместить папки?

NiOl 05-04-2010 15:39 1385461

1. Прям "Операция-Ы" - "извините, не НАШ, а ВАШ!" - этот скрипт точно не мой, я не люблю переменные записывать в таком формате, да и ремарки через двоеточие - моветон. (ну да это не вопрос, а так, шутки ради)
2. Если вывести DIR с ключем /A - на экране окажутся все файлы и каталоги, а с ключом /A:D - исключительно каталоги (попробуйте в командной строке). Далее, маска файлов/каталогов. До XP маска вида ??.??.???? работала однозначно, а сейчас выходит так, что последний знак вопроса является астериском
3. Папки перемещать очень сложно, появлется куча искажений там, где в файлах и папках встречаются спецсимволы типа пробела и прочих. Самый простой (но медленный ) способ - скопировать xcopy и затем удалить.
4. Вот аккуратный подсчет времени - проблема, которой я ниразу не баловался.
Если проблему можно описать другим способом, с более простыми условия, тогда можно попробовать...

zavoruev 05-04-2010 15:51 1385468

с удовольствием))) Мне надо что бы в папке оставались файлы недельной давности, этот скрипт я взяд в качестве примера, т.к на рабоих файлах эксперементировать не стал! Хотел добиться одного, перемещение каталогов, а с файлами было бы легче.

Есть папка, в нее скапливаются выгрузки из 1С, формат файла таков DATA260.ARJ и если файл большой то он вот в таком формате DATA265.A01, DATA265.A02, DATA265.A03. эти выгрузки происходят раз в день а иногда и 2 раза. мне необходимо что бы в данной папке после отработки скрипта оставались только файлы недельной давности (их может быть 5, если формат такой DATA260.ARJ, или 15 если формат токой DATA265.A02). Ни каких спец. символов нет. Эти файлы перемещаются для бэкапа в другую папку, где раз в месяц делается бэкап winrar.

zavoruev 05-04-2010 16:57 1385505

Сейчас попробЫвал сделать тестовый скрипт не для перемещения а для копирования созданных каталогов! результата нет! Вот код:
@Echo Off
:: Параметры скрипта, 0 < $OLD < 29!
:: $OLD - столько ДНЕЙ храним архивы
Set $SRC=D:\obmen1
Set $DST=D:\Backup_Obmen1
Set $OLD=1
:: Находим текущие день/месяц/год
For /F "Tokens=1 Delims=." %%i In ('WMIC OS Get LocalDateTime^|Find "."') Do Set $Time=%%i
Set $Y=%$Time:~0,4%&Set $M=0%$Time:~4,2%&Set $D=0%$Time:~6,2%
Set $M=%$M:~-2%&Set $D=%$D:~-2%
:: Создаем каталог
Mkdir %$SRC%\%$D%.%$M%.%$Y%\

:: копируем старые каталоги (файлы)
Call :GetOldDate %$OLD%
For /F "Tokens=1-3 Delims=." %%i In ('DIR /B/A:D %$SRC%\??.??.??') Do If %%k%%j%%i LEQ %$Y%%$M%%$D% XCopy /S/E/D/C/Q "%$SRC%\%%i.%%j.%%k %$DST%\"

:: Выход
EXIT

:GetOldDate
:: -----------------------------------
:: Расчет даты, предшествующей текущей
:: заданное количество дней (< 29)
:: -----------------------------------
Set /A $D -= %1
If %$D% GTR 0 GoTo GetOldDate_2
:: Месяц, год, дней в месяце
Set /A $M=%$M%+11-((%$M%+10)/12)*12
If %$M% EQU 12 Set /A $Y-=1
For /F "Tokens=%$M%" %%i In ("31 28 31 30 31 30 31 31 30 31 30 31") Do Set $X=%%i
If %$M% NEQ 2 GoTo GetOldDate_1
:: Февраль високосного года
Set /A $B1=%$Y%-(%$Y%/4)*4
Set /A $B2=%$Y%-(%$Y%/100)*100
Set /A $B3=%$Y%-(%$Y%/400)*400
If 0 EQU %$B1% If 0 NEQ %$B2% Set /A $X+=1
If 0 EQU %$B3% Set /A $X+=1
:: День месяца
:GetOldDate_1
Set /A $D=%$D%+%$X%-((%$D%+%$X%-1)/%$X%)*%$X%
:: Форматирование даты
:GetOldDate_2
Set $M=0%$M%&Set $D=0%$D%
Set $M=%$M:~-2%&Set $D=%$D:~-2%
GoTo :EOF

NiOl 05-04-2010 17:56 1385534

Насколько понимаю - каталог бэкапа не содержит подкаталогов, т.е. достаточно переносить только файлы.
Предлагаю такой вариант решения задачи (если устроит - смогу быстренько накидать) - в папке, где запускается скрипт, остаются все файлы с 5 РАЗЛИЧНЫМИ НАИСВЕЖАЙШИМИ датами.
Возможные глюки: Если по какой-то причине в какой-то из дней не появилось новых файлов, то после скрипта останутся файлы не за последние 5 дней, а на 1 день больше.
Как такой вариант?

ЗЫ: Архивировать *.ARJ винраром - только прибавлять в весе...

NiOl 05-04-2010 18:24 1385550

Вот:
Код:

@echo off
SetLocal EnableExtensions
SetLocal EnableDelayedExpansion

set Dst=C:\TEMP\

for /f "tokens=* delims=" %%F in ('dir /a-d /b /o-d') do if "!N!"=="5" (
move /Y %%F %Dst%
Echo Moving %%F ^(!D!^) Err=!ErrorLevel! >>Last5.log
) else (
set D=%%~tF
set D=!D:~0,10!
if not "!D!"=="!P!" (
set P=!D!
set /a N+=1
)
echo Skiping %%F ^(!D!, wait=!N!^)>>Last5.log
)


zavoruev 07-04-2010 09:18 1386824

NiOl, , все хорошо, только я не пойму где в этом скрипте указана директории куда перемещать файлы.
Как я понимаю
Цитата:

Цитата NiOl
set Dst=C:\TEMP »

это каталог откуда перемещаются файлы,
и что это за файл
Цитата:

Цитата NiOl
Last5.log »

, что в него записывается?

NiOl 07-04-2010 12:10 1386948

1. Запускать скрипт нужно из каталога, откуда файлы переносятся
2. Dst=C:\TEMP - это как раз папка, куда они переносятся. В сырце остался каталог, на котором я проводил проверку на своем компе.
3. Поскольку этот батник оставлял файлы за последние 5 разных дат, то рабочее название его было Last5.bat, и соответственно лог того, что делалось кидалось в файл Last5.log. Конечно, по-хорошему надо было написать так: %~dpn0.log или %~n0.log и имя лог-файла автоматом соответствовало бы имени скрипта, но я очень торопился и было лень сделать все красиво. Вообще, в лог нужно еще кидать дату/время, иначе это не лог...

zavoruev 07-04-2010 12:21 1386968

Как я понимаю, скрипт должен лежать в той папке где и перемещаемые файлы???? если в другой папке то скрипт не выполнится???? По шедуллеру можно этот скрипт выполнять?

NiOl 07-04-2010 13:14 1387018

Скрипт лучше всего держать в отдельной папке, вместе с другими скриптами, можно где-нить в софте. При этом скрипт будет аналогичен любой другой программе/внешней команде - можно вызывать практически откуда угодно (при всех ограничениях скриптов их несомненный плюс - открытый исходный текст, не требующий спец.софта для внесения изменений).
А вот запускать этот скрипт надо именно в папке-источнике, например лежит в D:\SOFT\Scripts\, а запускается (например поле "start in" в ярлыке) в E:\DB\1C\BackUp\, при этом отличие лог-файлов %~dpn0.log от %~n0.log будет в том, что в певом случае лог-файл ведется там, где расположен сам скрипт (D:\SOFT\Scripts\), а во втором случае - там, из какой папки запущен (E:\DB\1C\BackUp\).
Подобные скрипты обычно по шедулеру и запускаются.

zavoruev 07-04-2010 13:34 1387028

NiOl, ты все очень подробно расписал, спасибо! Я только не пойму, как можно в шедулере запустить скрипт который лежит в C:\scripts\ что бы он запускался в D:\Obmen1C\ !! Не могу это сделать, подскажите как? Очень нужно!)

NiOl 07-04-2010 13:58 1387052

Думаю, что Вы уже создали "задание" для шедула. Теперь редактируем его (правая кнопка мыши - свойства)

В первой вкладке все основное, что нам нать:
1. Run: (строка запуска) = C:\scripts\script.bat
2. Start in: (запускать в каталоге) = D:\Obmen1C\
3. Comments (примечания) - на свое усмотрение, вообще полезно подписывать, какое задание для чего, например "пятничная чиска бэкапов 1С"
4. Run as (запускать от имени) = учетная запись, имеющая право логиниться на этот сервер и вносить необходимые изменения (удалять файлы в папке "D:\Obmen1C\") и рядом кнопка для указания пароля этой учетки.
5. Enabled (разрешено) - если галочка стоит, то задание будет исполняться.

На второй вкладке указывается периодичность вызова задания. В списке явно нехватает пунктов "каждые nn часов" и "каждые nn минут" ;)

На третей вкладке дополнительные опции, определяющие некоторые условия выполнения задания, для большинства задач параметры по-умолчанию вполне подходят.

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

Iska 07-04-2010 14:02 1387057

«Рабочая папка:» в свойствах созданного задания.

zavoruev 07-04-2010 14:09 1387067

Всем спасибо за ответы!
NiOl, А как бы доработать приведенный в топике скрипт, учитывая то что расчет даты правильный, и необходимо только переместить файлы старше 5 дней (переменная OLD) в другую папку. Как я понимаю тут не праильно работает во эта команда, может все таки попробуем его доработать)))!!!
Цитата:

Цитата zavoruev
For /F "Tokens=1-3 Delims=." %%i In ('DIR /B/A:D %$SRC%\??.??.????') Do If %%k%%j%%i LEQ %$Y%%$M%%$D% move /Y "%$SRC%\%%i.%%j.%%k %$DST%\" »

Буду очень признателен за оказанную помощь!

NiOl 07-04-2010 14:53 1387109

Цитата:

Цитата zavoruev
Всем спасибо за ответы!
NiOl, А как бы доработать приведенный в топике скрипт, учитывая то что расчет даты правильный, и необходимо только переместить файлы старше 5 дней (переменная OLD) в другую папку. Как я понимаю тут не праильно работает во эта команда, может все таки попробуем его доработать)))!!!
Цитата zavoruev:
For /F "Tokens=1-3 Delims=." %%i In ('DIR /B/A:D %$SRC%\??.??.????') Do If %%k%%j%%i LEQ %$Y%%$M%%$D% move /Y "%$SRC%\%%i.%%j.%%k %$DST%\" »
Буду очень признателен за оказанную помощь! »

Логгер: на форуме молчание 15 минут... :lol:

наскоро просмотрев исходный скрипт, уделив особое вниманеи указанное строке, у меня вышло 1 предупреждение и 4 ошибки:

1. Процедура GetOldDate выходит по команде GoTo :EOF и я не уверен, насколько это допустимо. Обычно принято завершать процедуры командой Exit /b
(Рекомендую на всякий пожарный заменить последню строку скрипта)

2. Команда DIR в таком виде даст только названия каталогов, а не файлов.
3. Комада IF без ключа /i не воспринимает сравнение числовых величин.
4. В Команде Move указан только Источник, а Приемник не указан (пропущена пара кавычек).
5. У переносимых файлов нет расширения? (сомневаюсь)
В итоге строка переноса должна выглядить так: For /F "Tokens=1-3 Delims=." %%i In ('DIR /B /A %$SRC%\??.??.????.*') Do If /i %%k%%j%%i LEQ %$Y%%$M%%$D% move /Y "%$SRC%\%%i.%%j.%%k.*" "%$DST%\"

zavoruev 12-05-2010 17:03 1411757

Уважаемы NiOl,
при тестировании выполнения данного скрипта, премещение файлов не происходит, вот ошибки в логе
Skiping copy file.cmd (27.04.2010, wait=1)
Skiping creat and copy folders(Є®«-ў® ¤*Ґ©).cmd (05.04.2010, wait=2)
Skiping Creat and copy folders(Є®«-ў® Ї*Ї®Є).cmd (05.04.2010, wait=2)
Skiping Creat folders.cmd (01.04.2010, wait=3)
Skiping Last5.log (27.04.2010, wait=1)
Skiping copy file.cmd (27.04.2010, wait=1)
Skiping creat and copy folders(Є®«-ў® ¤*Ґ©).cmd (05.04.2010, wait=2)
Skiping Creat and copy folders(Є®«-ў® Ї*Ї®Є).cmd (05.04.2010, wait=2)
Skiping Creat folders.cmd (01.04.2010, wait=3)
Skiping Last5.log (27.04.2010, wait=1)
Skiping copy file.cmd (27.04.2010, wait=1)
Skiping creat and copy folders(Є®«-ў® ¤*Ґ©).cmd (05.04.2010, wait=2)
Skiping Creat and copy folders(Є®«-ў® Ї*Ї®Є).cmd (05.04.2010, wait=2)
Skiping Creat folders.cmd (01.04.2010, wait=3)

megaloman 12-05-2010 18:21 1411799

WinRar решает Вашу проблему в одну строчку в назначенных заданиях, и не надо изобретать велосипед. Разве что проблема в лицензии ... Если хотите, напишу
Цитата:

Цитата NiOl
1. Запускать скрипт нужно из каталога, откуда файлы переносятся »

- это приведёт в конце концов к тому, что и скрипт перенесётся и запускать будет нечего. Это совершенно неверно, просто надо указывать полный путь в скрипте.

megaloman 12-05-2010 19:51 1411843

Основная проблема - отнять от текущей даты заданное кол-во дней. В решении похожей задачи заимствовал процедуры. Вот батник, который помещаете в назначенные задания (но rar лучше, всё равно старьё надо архивировать!)
Код:

Echo off
rem -------------------
rem Перенос файлов не новее указанного числа дней из одной директории в другую
rem Предполагаю, что Дата в системе выдаётся в формате дд.мм.гггг чч:мм и т д (разделитель не важен)
rem -------------------

rem ------------------------------ Кол-во дней за которые не перемещаем файлы
Set NDays=5

rem ------------------------------ Где находятся все файлы (можно указать маску)
Set WhereAll=H:\Delete\All Files\*.*

rem ------------------------------ Куда перемещаем старые
Set WhereOld=H:\Delete\Old Files\

rem Выделяю из текущей даты день, месяц, год

Set Dt=%Date%

Set Day=%Dt:~0,2%
If %Day:~0,1%==0 Set Day=%Day:~1,1%

Set Mon=%Dt:~3,2%
If %Mon:~0,1%==0 Set Mon=%Mon:~1,1%

Set Yea=%Dt:~6,4%

Call :MinusDays

Set Dt=%Yea%%Mon%%Day%

FOR %%i IN ("%WhereAll%") DO Call :MoveFromTo "%%i"

GoTo :End

rem -------------------------------------------------------------
rem Процедура перемещает файлы не новее указанной даты (формат ггггммдд)
rem -------------------------------------------------------------

:MoveFromTo

Set D=%~t1
Set D=%D:~6,4%%D:~3,2%%D:~0,2%

If %D% LEQ %Dt% Move "%~f1" "%WhereOld%"

GoTo :End


rem -------------------------------------------------------------
rem Процедура отнимает от даты заданное число дней
rem Дата содержится в трёх переменных Day Mon Yea
rem -------------------------------------------------------------

:MinusDays

For /L %%D IN (1,1,%NDays%) Do Call :OldDt

If %Day% LSS 10 Set Day=0%Day%
If %Mon% LSS 10 Set Mon=0%Mon%

rem Echo %Yea% %Mon% %Day%
rem Pause

GoTo End

rem ---------------------------------
rem Процедура отнимает от даты 1 день
rem ---------------------------------

:OldDt
Set /A Day=%Day%-1

If %Day% GTR 0 GoTo End

Set Day=31

Set /A Mon=%Mon%-1

If %Mon% GTR 0 GoTo BotDay

Set Mon=12
Set /A Yea=%Yea%-1

:BotDay
 
If Not %Mon%==2 GoTo Mon30
Set Day=28

Set iYea=%Yea%
Set /A iYea=%iYea%/4
Set /A iYea=%iYea%*4

If %Yea%==%iYea% Set Day=29
GoTo End

:Mon30
If %Mon%==4 Set Day=30
If %Mon%==6 Set Day=30
If %Mon%==9 Set Day=30
If %Mon%==11 Set Day=30

GoTo End
rem ---------------------------------


:End

Батник располагайте где угодно, только не в директории откуда переносите файлы, в назначенном задании укажите его полное имя (с путем)

zavoruev 28-05-2010 11:21 1422786

А что Вы там говорили по поводу rar.exe. Готов выслушать Ваши предложения!

megaloman 28-05-2010 14:04 1422944

"C:\Program Files\WinRar\winrar.exe" a -df -to7d -agYYYYMMDD{_NameArc} "H:\Kuda\.rar" "T:\Otkuda\*.*"

Ключ -df удалит заархивированные файлы
Ключ -to7d приведёт к архивации файлов старше 7 дней

Ключ -agYYYYMMDD{_NameArc} - добавит к имени архива дату и символы. Я имя архива написал пустым (.rar). _NameArc - НапишИте своё, подходящее по смыслу.
После отработки WinRar для сегодня получим архив под именем 20100528_NameArc.rar в папке H:\Kuda\

"H:\Kuda\.rar" - путь к заархивированным файлам (напИшите своё)
"T:\Otkuda\*.*" - где лежат архивируемые файлы (напИшите своё)

Описание ключей в справочной системе WinRar
Вызов WinRar можно поместить в назначенные задания


Время: 16:00.

Время: 16:00.
© OSzone.net 2001-