Войти

Показать полную графическую версию : [решено] Найти, есть ли в папке (и подпапках) изменённые файлы с указанной даты


Страниц : 1 [2]

frid-karatel
09-05-2011, 13:06
Всех с Днём Победы! Ура!

В-общем, доделал я то, что хотел... :)
Вот результат:
:: ==================================================================================================== ===============================
:: >> Основные настройки скрипта
@ECHO OFF
SETLOCAL enabledelayedexpansion
:: << << <<
:: ==================================================================================================== ===============================
:: >> Назначаем необходимые переменные
:: Папка, куда необходимо копировать резервные копии
SET $BACKUP_DIR_PARENT=S:\Backup
:: Путь до архиватора
SET $WINRAR=C:\Program Files\WinRAR\WinRAR.exe
:: << << <<
:: ==================================================================================================== ===============================
REM >> Определяем массив папок для копирования
SET $FOLDER:01=C:\Documents
SET $FOLDER:02=C:\Letters
SET $FOLDER:03=C:\ThirdFolder
:: ...и так далее...
:: << << <<
:: ==================================================================================================== ===============================
:: >> Список файлов, которые не учитывать при проверки изменения папки
SET $FILE_EXCLUDE:01=Thumbs.db
SET $FILE_EXCLUDE:02=.access_log
SET $FILE_EXCLUDE:03=.error_log
SET $FILE_EXCLUDE:04=.cookie
:: << << <<
:: ==================================================================================================== ===============================
:: >> Проход по всем папкам и проверка, есть ли изменения
FOR /f "tokens=2 delims==" %%f IN ('SET $FOLDER') DO (
SET $FOLDER_CURRENT=%%f

REM >> Определяем папку для резервных копий текущей папки
SET $BACKUP_DIR=!$BACKUP_DIR_PARENT!\!COMPUTERNAME!\!$FOLDER_CURRENT::=!
REM << << <<

REM >> Если папки не существует, то создаём её
IF NOT EXIST "!$BACKUP_DIR!" (
MKDIR "!$BACKUP_DIR!"
)
REM << << <<

REM >> Определение даты последней резервной копии
REM Через команду DIR получаем список файлов с расширением RAR
REM Затем выполняем поиск самого свежего (последнего изменённого) файла
REM Дату последнего изменения устанавливаем исходя из даты изменения самого свежего файла
SET $LAST_MODIFIED=0
PUSHD "!$BACKUP_DIR!"
FOR /f "tokens=1,2,4" %%a IN ('DIR /TW /A-D-H *.rar ^| findstr /B "[0-9]"') DO (
FOR /f "tokens=1-5 delims=.:" %%i IN ("%%a.%%b") DO (
IF "%%k%%j%%i%%l%%m" GTR "!$LAST_MODIFIED!" (
SET $LAST_MODIFIED=%%k%%j%%i%%l%%m
)
)
)
POPD
REM << << <<

REM >> Выполняем поиск изменённых файлов
SET $IS_MODIFIED=
PUSHD "!$FOLDER_CURRENT!"
FOR /f "tokens=1,2,4" %%a IN ('DIR /S /TW /A-D-H ^| findstr /B "[0-9]"') DO (
IF NOT DEFINED $IS_MODIFIED (
SET $CURRENT_FILE=%%c

REM >> Проверяем, находится ли файл в исключениях
SET $EXTRUDED=
FOR /f "tokens=2 delims==" %%e IN ('SET $FILE_EXCLUDE') DO (
IF NOT DEFINED $EXTRUDED (
IF "%%e"=="!$CURRENT_FILE!" (
SET $EXTRUDED=1
)
)
)
REM << << <<

REM >> Если файл не находится в исключениях, то обрабатываем его
IF NOT DEFINED $EXTRUDED (
FOR /f "tokens=1-5 delims=.:" %%i IN ("%%a.%%b") DO (
IF "%%k%%j%%i%%l%%m" GTR "!$LAST_MODIFIED!" (
SET $IS_MODIFIED=1
)
)
)
REM << << <<
)
)
POPD
REM << << <<

REM >> Если в папке имеются изменения, то сделать её резервную копию
IF DEFINED $IS_MODIFIED (
PUSHD "!$FOLDER_CURRENT!"

REM >> Если изменения есть, то упаковываем папку в архив
REM A Добавить в архив
REM -CFG- Игнорировать профиль по умолчанию и переменную окружения
REM -DH Открывать совместно используемые файлы
REM -EP1 Исключить базовую папку из пути
REM -INUL Не выводить сообщения об ошибках
REM -M5 Метод сжатия: максимальный
REM -R Включая вложенные папки
REM -S Создать непрерывный архив
REM -TL Установить время архива по времени новейшего файла
REM -Y Подразумевать ответ "Да" на все вопросы
REM -X{NAME} Не обрабатывать файл/папку NAME. [-x*\temp\] - искл. все папки temp и файлы внутри папок temp
"!$WINRAR!" A "backup" -CFG- -DH -EP1 -INUL -M5 -R -S -TL -Y "!$FOLDER_CURRENT!\"
REM << << <<

REM >> Определяем дату самого последнего изменения в папке исходя из даты созданий архива
REM Через команду DIR получаем строку, содержащую информацию о файле backup
REM Затем берём из строки дату изменения ГГГГ.ММ.ДД и время ЧЧ:ММ
REM Согласно полученой дате устанавливаем имя RAR-архива для резервной копии
FOR /f "tokens=1,2" %%a IN ('DIR /TW /A-D-H backup.rar ^| findstr /B "[0-9]"') DO (
FOR /f "tokens=1-5 delims=.:" %%i IN ("%%a.%%b") DO (
SET $BACKUP_FILENAME=%%k-%%j-%%i %%l-%%m
)
)
REM << << <<

REM >> Перемещаем созданный архив в папку для резервных копий
MOVE "backup.rar" "!$BACKUP_DIR!\!$BACKUP_FILENAME!.rar"
REM << << <<

POPD
)
REM << << <<
)
:: << << <<
:: ==================================================================================================== ===============================

Тут ещё есть пара вариантов, которые хочу доработать.
И по одному из них не знаю, как сделать...

В данном случае у меня есть список файлов, которые не учитывать при проверке на последнее изменение - это $FILE_EXCLUDE.
Хотелось бы иметь возможность исключать не только файлы, но и подпапки.
Дело в том, что в некоторых проектах есть HTML-кэш, который изменяется почти каждый час...
Соответственно, папку \cache\ и все её подфайлы/подпапки НЕ надо учитывать при проверке на изменение.
Как такое дело реализовать?

amel27
09-05-2011, 13:25
В бесконечном цикле походу goto вообще не работает, даже goto:eof, только exit »На самом деле он и в конечном цикле не работает. Только после завершения цикла переходит на метку - которая может быть в батнике где угодно (в т.ч. оказаться в каком-нибудь цикле). Это отчетливо видно из второго примера.

Foreigner
09-05-2011, 14:28
На самом деле он и в конечном цикле не работает. Только после завершения цикла переходит на метку »
Из второго примера как раз видно что цикл прервался, но сначала отработала метка:

@echo off
setlocal

for /l %%i in (1,1,10) do (

echo 1: %%i
if %%i equ 3 goto:break
echo 2: %%i

:break
echo 3: %%i

)
echo end


1: 1
2: 1
3: 1
1: 2
2: 2
3: 2
1: 3
3: %i -- это уже вне цикла, т.к. не работает встроенная переменная %%i
end

Но все же это из разряда хака, нештатное поведение. Обязательное наличие команды на выполнение ( тот же rem )

amel27
10-05-2011, 07:08
цикл прервался, но сначала отработала метка»
Во-первых, цикл тут как раз не должен прерываться. То, что он останавливается на команде GoTo: говорит как раз в пользу того, что метка не отрабатывает как положено.
Во-вторых, если включить ECHO ON, то видно, что батник на самом деле отрабатывает ВСЕ значения %%i, хотя после GoTo уже вхолостую. Т.е. штатное прерывание циклов FOR не предусмотрено.
В-третьих, ошибка "обязательного наличия команды" никак не связана с циклом - это особенность блока, ограниченного круглыми скобками, пример:(
:LABEL
)
То, что метку интерпретатор считает незавершенной командой говорит как раз в пользу того, что использование меток в блоке не предусмотрено. Блок считывается интерпретатором целиком и выполняется как одна (кэшированная) команда, в то время как переход по метке является самостоятельной файловой операцией (построчного чтения батника), т.е. может исполняться только между "командами".

Foreigner
10-05-2011, 16:56
amel27,
Действительно @echo on показателен и это объясняет отказ от выхода из бесконечного цикла, но все равно поведение не совсем объяснимо. Например:

@echo on
setlocal

for /l %%i in (0,1,10) do (

set "var_%%i=%%i"
if %%i equ 5 goto:break

:break
rem

)
set var_

Т.е. получается, что после перехода на метку цикл отрабатывает в холостую. Что в принципе может когда-либо пригодиться, но согласен "if решает".

amel27
10-05-2011, 17:34
получается, что после перехода на метку цикл отрабатывает в холостую »он отрабатывает вхолостую ПЕРЕД фактическим переходом на метку

команда, которая "сносит крышу" CMD-интерпретатору: :)(.&:
P.S. строка должна быть последней в батнике, БЕЗ завершающего CRLF

Foreigner
10-05-2011, 19:26
команда, которая "сносит крышу" CMD-интерпретатору: »
Забавно.

amel27
11-05-2011, 03:30
Ещё один момент - приняв правило "не использовать метки в блоках кода, ограниченных круглыми скобками", мы будем вынуждены принять и его следствие: отказаться от применения в блоках нестандартных комментариев по типу меток "::" - только REM.
(
:: Комментарий
)

Foreigner
11-05-2011, 06:55
amel27,
Ну так "::" не комментарий, а метка. С таким же успехом можно:

@echo off

echo 1
:внимание!!! Это как бы комментарий

echo 2 & :пояснение: выводим цифру 2

amel27
11-05-2011, 07:12
Ну так "::" не комментарий, а метка. »по сути да, но часто в руководствах этот факт игнорируется, потом привыкаем и ставим тупо "по привычке"... и еще удивляемся почему не работает... ))




© OSzone.net 2001-2012