Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Найти, есть ли в папке (и подпапках) изменённые файлы с указанной даты

Ответить
Настройки темы
CMD/BAT - [решено] Найти, есть ли в папке (и подпапках) изменённые файлы с указанной даты

Новый участник


Сообщения: 14
Благодарности: 0

Профиль | Отправить PM | Цитировать


Доброго времени суток!

Возник вопрос...
Как можно средствами BAT-файла найти, есть ли изменённые файлы в указанной папке (включая подкапки)?

Вкратце опишу, для чего мне это необходимо:
1. Указываю папку через SET $DEST_DIR=C:\Documents
2. Затем скрипт проверяет, есть ли в папке изменившиеся файлы (хотя бы один)
3. Если есть хотя бы один изменённый файл, то скрипт запускает WinRAR из консоли и делает т.н. резервную копию всей папки
4. Затем созданный архив перемещает на сетевой диск...

Отправлено: 18:41, 08-05-2011

 

Новый участник


Сообщения: 14
Благодарности: 0

Профиль | Отправить PM | Цитировать


Всех с Днём Победы! Ура!

В-общем, доделал я то, что хотел...
Вот результат:
Код: Выделить весь код
:: ===================================================================================================================================
:: >> Основные настройки скрипта
@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\ и все её подфайлы/подпапки НЕ надо учитывать при проверке на изменение.
Как такое дело реализовать?

Отправлено: 13:06, 09-05-2011 | #21



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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


Googler


Сообщения: 3665
Благодарности: 1563

Профиль | Отправить PM | Цитировать


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

Отправлено: 13:25, 09-05-2011 | #22


Ветеран


Сообщения: 1758
Благодарности: 966

Профиль | Цитировать


Цитата amel27:
На самом деле он и в конечном цикле не работает. Только после завершения цикла переходит на метку »
Из второго примера как раз видно что цикл прервался, но сначала отработала метка:
Код: Выделить весь код
@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 )

Отправлено: 14:28, 09-05-2011 | #23


Googler


Сообщения: 3665
Благодарности: 1563

Профиль | Отправить PM | Цитировать


Цитата Foreigner:
цикл прервался, но сначала отработала метка»
Во-первых, цикл тут как раз не должен прерываться. То, что он останавливается на команде GoTo: говорит как раз в пользу того, что метка не отрабатывает как положено.
Во-вторых, если включить ECHO ON, то видно, что батник на самом деле отрабатывает ВСЕ значения %%i, хотя после GoTo уже вхолостую. Т.е. штатное прерывание циклов FOR не предусмотрено.
В-третьих, ошибка "обязательного наличия команды" никак не связана с циклом - это особенность блока, ограниченного круглыми скобками, пример:
читать дальше »
Код: Выделить весь код
(
:LABEL
)

То, что метку интерпретатор считает незавершенной командой говорит как раз в пользу того, что использование меток в блоке не предусмотрено. Блок считывается интерпретатором целиком и выполняется как одна (кэшированная) команда, в то время как переход по метке является самостоятельной файловой операцией (построчного чтения батника), т.е. может исполняться только между "командами".

Последний раз редактировалось amel27, 11-05-2011 в 03:31. Причина: очепятка

Это сообщение посчитали полезным следующие участники:

Отправлено: 07:08, 10-05-2011 | #24


Ветеран


Сообщения: 1758
Благодарности: 966

Профиль | Цитировать


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 решает".

Отправлено: 16:56, 10-05-2011 | #25


Googler


Сообщения: 3665
Благодарности: 1563

Профиль | Отправить PM | Цитировать


Цитата Foreigner:
получается, что после перехода на метку цикл отрабатывает в холостую »
он отрабатывает вхолостую ПЕРЕД фактическим переходом на метку


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

Отправлено: 17:34, 10-05-2011 | #26


Ветеран


Сообщения: 1758
Благодарности: 966

Профиль | Цитировать


Цитата amel27:
команда, которая "сносит крышу" CMD-интерпретатору: »
Забавно.

Отправлено: 19:26, 10-05-2011 | #27


Googler


Сообщения: 3665
Благодарности: 1563

Профиль | Отправить PM | Цитировать


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

Последний раз редактировалось amel27, 11-05-2011 в 04:29.


Отправлено: 03:30, 11-05-2011 | #28


Ветеран


Сообщения: 1758
Благодарности: 966

Профиль | Цитировать


amel27,
Ну так "::" не комментарий, а метка. С таким же успехом можно:
Код: Выделить весь код
@echo off

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

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

Отправлено: 06:55, 11-05-2011 | #29


Googler


Сообщения: 3665
Благодарности: 1563

Профиль | Отправить PM | Цитировать


Цитата Foreigner:
Ну так "::" не комментарий, а метка. »
по сути да, но часто в руководствах этот факт игнорируется, потом привыкаем и ставим тупо "по привычке"... и еще удивляемся почему не работает... ))

Отправлено: 07:12, 11-05-2011 | #30



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Найти, есть ли в папке (и подпапках) изменённые файлы с указанной даты

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
CMD/BAT - [решено] Нужно найти все файлы *.log в папке dir и подпапках и заменить на файлы нулевой длины dclxvi Скриптовые языки администрирования Windows 4 04-07-2012 21:28
Любой язык - Нужно быстро (!) добавить/удалить строку во все файлы указанной директории Possessed Скриптовые языки администрирования Windows 6 04-10-2011 22:29
CMD/BAT - [решено] две функции по mp3 (узнать продолжительность и найти все mp3 файлы в папке) tor4ok11 Скриптовые языки администрирования Windows 5 22-11-2010 07:17
Доступ - Доступ через сеть к указанной общей папке Makcermakcer Microsoft Windows Vista 0 29-08-2009 23:06
[решено] Найти последние изменённые файлы hasherfrog Программирование в *nix 3 22-08-2008 15:32




 
Переход