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

Ingolder 02-12-2009 18:10 1285223

Как создать бат, чтобы проверял число месяца?
 
Задача такая.

Есть файл в директории 1.
Его нужно один раз в месяц копировать из директории 1 в директорию 2.
Эта операция должна происходить в промежутке с 20 по 30 число месяца (и не больше одного раза за период, т.е. если мы двадцать третьего числа запустили бат, он сработал, то чтобы в этом месяце он больше уже не срабатывал).


Не доходит, помогите пжлст

AHTuKuJIJIeP 02-12-2009 22:22 1285431

Код:

@echo off
rem Пример единоразового копирования файла filename.txt
title=Copier of files
SetLocal EnableExtensions EnableDelayedExpansion
SET DD=%DATE:~0,2%
echo %DD% | findstr "20 21 22 23 24 25 26 27 28 29 30" >nul
if !errorlevel!==0 (
if exist C:\DIR1\filename.txt (
if not exist C:\DIR2\filename.txt (
copy C:\DIR1\filename.txt C:\DIR2\filename.txt
)
)
)


NiOl 03-12-2009 11:53 1285770

AHTuKuJIJIeP, сделано неплохо, вот только копия файла уже существует и скрипт не отработает а если убрать проверку существования копии (которая сама не исчезнет), то при повторном запуске твой скрипт заново будет копировать файл.

предлагаю вести лог и по нему и отслеживать была ли сделана копия:
Код:

@Echo off
SetLocal EnableExtensions

Set File=C:\1\MyFile.dat
Set BackUp=C:\2\

set Msg=Nothing to do
set tm=%time::=-%
set tm=%date:~6,4%-%date:~3,2%-%date:~0,2%_%tm:~0,-3%

set Chk=%tm:~8,2%
if /I %Chk% LSS 20 Goto End

set Chk=%tm:~0,7%
for /f "Tokens=1,2* Delims=:" %%D in ('FindStr /i /c:"Synchronization Done" %~dpn0.log') do set Last=%%D
set Last=%Last:~0,7%
if "%Chk%"=="%Last%" Goto End

copy /y %File% %BackUp%
if %ErrorLevel%==0 (set Msg=Synchronization Done
) else set Msg=Synchronization Failed !!!

:End
echo %tm%: %Msg%>>%~dpn0.log

* 2 замечания (фичи ;) ):
1. если копия файла окажется защищена или занята, то копирования не произойдет - смотрите лог
2. малость упростил проверку - копирование возможно не с 20 по 30, а просто с 20 (т.е. и 31го тоже)
Если второе замечание критично - легко поправлю проверку.

amel27 03-12-2009 11:54 1285772

Код:

Set SRC=C:\TEST1\file.txt
Set DST=C:\TEST2\

:: Проверка на день месяца

If "%DATE:~0,1%"=="0" (Set $D=%DATE:~1,1%) Else Set $D=%DATE:~0,2%
If %$D% LSS 20 Exit /B 1

:: Проверка на последний запуск (ini-файл)

For /F "UseBackQ" %%i In ("%~dpn0.ini") Do Set $L=%%i
If "%$L%"=="%DATE:~3,2%" Exit /B 2

:: Копирование / сохранение параметров запуска

XCOPY "%SRC%" "%DST%" /Y/R
If Not ErrorLevel 1 Echo %DATE:~3,2%>"%~dpn0.ini"


Ingolder 06-12-2009 18:46 1287992

NiOl, здОрово, спасибо, ваше работает. Вы не могли бы как-то всё прокомментировать для тех, кто не очень? А т оя не очень..


amel27, а в вашем случае он полюбому копирует с заменой..

amel27 07-12-2009 08:22 1288380

Цитата:

Цитата Ingolder
полюбому копирует с заменой »

исправил опечатку (в последней строке), добавил комментарий

Ingolder 07-12-2009 17:10 1288790

amel27, вроде работает.
Единственное, что - очень вас прошу, для тех кто совсем в танке, прокомментируйте поподробнее, не "в общем", а "как и чего".

очень прошу :cry:

NiOl 07-12-2009 21:28 1288993

Цитата:

Цитата Ingolder
Вы не могли бы как-то всё прокомментировать для тех, кто не очень? А т оя не очень.. »

Чтож, попробую, понимаю как сложно без понятного примера разбираться в чем-то новом:

Откючаем эхо команд (чтоб сам скрип на экране не выводился) и разрешаем "новшества" в командах от Большого Билла
Код:

@Echo off
SetLocal EnableExtensions

Самое простое - указываем какой файл копируется и куда он копируется.
Код:

Set File=C:\1\MyFile.dat
Set BackUp=C:\2\

Сообщение для лог-файла "по-умолчанию"
Код:

set Msg=Nothing to do
Стандартная "макрокоманда" для получения тек. даты и времени в формате YYYY-MM-DD_HH-MM-SS (если в винде указать, что мы находимся в штатах, то работать не будет - там дата имеет вид MM/DD/YYYY). Первая строчка из переменной %time% (формат примерно такой: 20:30:19,54) заменяет все ":" на "-" и кладет в переменную %tm%.
Вторая строчка использует переменную %date% вида 07.12.2009 и из нее строит готовый текст, состоящий из: 4х символов с 6й позиции (год) + символ "-" + 2 символа с 3й позиции (месяц) + "-" + 2 символа с 0й позиции (число) + "_" + уже полученное время (вида 20-30-19,54, где ":" заменено на "-") без 3х последних символов. (уфф) * см. set /?
Код:

set tm=%time::=-%
set tm=%date:~6,4%-%date:~3,2%-%date:~0,2%_%tm:~0,-3%

Таким же образом берем из нашей даты %tm% 2 символа с текущим числом и проверяем, что сегодняшнее число меньше 20 ("LSS"="LeSS then", см. if /?). Если да - на выход, где выводится уже готовое сообщение в лог-файл.
Код:

set Chk=%tm:~8,2%
if /I %Chk% LSS 20 Goto End

Получаем от текущей даты первые 7 символов - год и месяц - будем их искать в лог-файле в строках с успешной синхронизацией.
Код:

set Chk=%tm:~0,7%
Выполняем внешнюю команду FindStr, которая ищет строку в файле(ах). Ключ /I говорит игнорировать регистр, а ключ /c:"" ищет указанную строку "строго", т.е. с указанными пробелами, не разрывая слова. И ищется все это в файле, полученном из имени батника (%0 - сам батник): модификатор d говорит взять имя диска, где лежит батник, p - путь, а n - имя батника без расширения, ну а разширение добавляем .log. Таким образом если %0 дает что-нить типа "FileSinc.bat", то %~dpn0.log выдаст с полным путем "D:\BackUp\FileSinc.log". (см. "call /?" и "for /?").
Но результат поиска будет выведен на экран, а нам надо затолкать его в переменные и анализировать. Поэтому команда вызывается внутри цикла, рабирающего строку или читающего текстовые файлы или перехватывающего вывод на экран (как в данном случае). В цикле сказано, что данные разделены на "столбцы" символом ":" (delims) и что нас интересует первый столбец в первой переменной (%%D), а второй и все остальные ("2*") столбцы - во вторую переменную (по алфавиту это будет %%E). (*задним числом можно сказать, что нам плевать на остальные столбцы - думал те данные понадобятся) Цикл пройдет по всем строкам, где FindStr нашел отметку об успешном копировании и первый столбец (с датой) по очереди положит в переменную %Last%. В итоге получим дату самого-присамого последнего копирования:
Код:

for /f "Tokens=1,2* Delims=:" %%D in ('FindStr /i /c:"Synchronization Done" %~dpn0.log') do set Last=%%D
Оставляем от даты последнего копирования только первые 7 символов - год и месяц.
Если год и месяц текущей даты и даты последнего копирования совпадают, значит копирование в этом месяце уже было и ничего не нужно делать - переходим в конец с уже заготовленным сообщением "Nothing to do".
Код:

set Last=%Last:~0,7%
if "%Chk%"=="%Last%" Goto End

Копируем файл без запроса на перезапись уже имеющегося файла (ключ /Y).
Если Код Выхода команды (Код Ошибки) Copy равен нулю - значит все прошло успешно (готовим соответствующее сообщение), в противном случае готовим другое сообщение, куда по-хорошему можно было добавить сам код ошибки (например 2="файл не найден" и т.д. - коды ошибок можно посмотреть в иНете. Особенность: переменную с Кодом Ошибки можно прочитать только раз - в следующий раз там будет результат, которым закончилось само чтение Кода Ошибки!)
Код:

copy /y %File% %BackUp%
if %ErrorLevel%==0 (set Msg=Synchronization Done
) else set Msg=Synchronization Failed !!!

Собственно все - вывод текущей даты с двоеточием на конце и текстом уже подготовленного сообщения в лог-файл *метки для перехода в батч-файлах начинаются с двоеточия. Некоторые "товарисчи" используют этот символ в качестве ремарки вместо команды rem. Это мовитон, использует лишние ресурсы (все метки интерпретатор должен помнить) и может привести к ошибке "на невнимательность".
Код:

:End
echo %tm%: %Msg%>>%~dpn0.log



Время: 23:46.

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