![]() |
Найти, есть ли в папке (и подпапках) изменённые файлы с указанной даты
Доброго времени суток!
Возник вопрос... Как можно средствами BAT-файла найти, есть ли изменённые файлы в указанной папке (включая подкапки)? Вкратце опишу, для чего мне это необходимо: 1. Указываю папку через SET $DEST_DIR=C:\Documents 2. Затем скрипт проверяет, есть ли в папке изменившиеся файлы (хотя бы один) 3. Если есть хотя бы один изменённый файл, то скрипт запускает WinRAR из консоли и делает т.н. резервную копию всей папки 4. Затем созданный архив перемещает на сетевой диск... |
frid-karatel,
Цитата:
Если надо обязательно найти, Код:
@echo off |
Мне необходимо не скопировать изменившиеся файлы, а узнать, есть ли изменения в папке, изменился ли хотя бы какой-нибудь жалкий файлик с даты, указанной мной...
Например, SET $CH_DATE=20110501. Если с этой даты есть хотя бы какие-нибудь изменения в папке, то выдать, так сказать, true, иначе false :) Более подробно... У меня на сетевом диске в папке Backup есть архивы WinRAR... У архивов имена: 2011-04-13, 2011-04-27, 2011-04-29, 2011-05-01 и т.д. Каждый день через планировщик Windows будет запускаться BAT-файл, который будет брать имя (дату создания) самого нового архива WinRAR. Затем в указанных мной папках будет выполняться поиск на наличие изменённых файлов. Если изменения есть, то будет создаваться новый архив WinRAR с именем как дата самого нового файла. После создания, архив будет перемещаться на сетевой диск в папку Backup. Во-от :) P.S.: Приведу пример, для чего это необходимо... Имеется локальный веб-сервер, на котором в сети держатся порядка 10ти сайтов и сервисов. Например, сегодня я решил улучшить один из сайтов, внёс изменения, поправил картинки/скрипты и т.п. Ночью, когда все спят и никаких изменений не производится, надо сделать резервную копию всей папки с этим сайтом, а не только изменённых файлов. Чтобы в случае чего можно было не восстановить какие-то файлы из резервной копии, а откатиться целиком на ту версию сайта, которая была, скажем, месяц назад... В остальных 9ти никаких изменений не произошло, соответственно резервные копии смысла делать нет. |
frid-karatel, для размышления: про атрибут файлов «архивный» и его применение в данном случае Вы в курсе? Можете попробовать что-то наподобие:
Код:
@echo off |
frid-karatel, по мне так вполне должно хватить возможностей WinRAR - он умеет сам искать файлы, измененные со времени последнего бэкапа (ключи -ac, -ao)
|
amel27, дык, автору вопроса надо «всю папку с сайтом», а не только архивные файлы. Глупость, конечно. Подобный подход автора к архивированию выглядит, по меньшей мере, нелепым: 3 Виды резервного копирования.
|
Расскажу более детально ситуацию, чтобы понять, почему я пошёл в этом направлении, а не взял какой-нибудь софт для бэкапа...
У нас есть сеть из 5ти компьютеров + 1 компьютер как-бы "серверный". На серверном компьютере стоят несколько HDD по 2Тб. Там же лежат разные резервные копии, дистрибутив и т.п. вещи. Там же запущен локальный WEB-сервер XAMPP. На нём хостятся с 5 локальных версий сайтов да всякие сервисы типа менеджера задач, органайзера, почты и т.п. Далее... Ведётся работа над N проектами. Допустим, 30 шт. За день могут быть изменены только 5 проектов, а то и вообще изменений не будет. Соответственно, надо проверять, были ли какие-нибудь изменения или нет, а потом уже делать резервную копию. Далее... Необходима полная резервная копия всей папки с проектом целиком, а не только измененных файлов. Чтобы через месяц-другой-третий можно было откатиться и посмотреть/сравнить с тем, что сейчас есть. Далее... Проекты могут содержать как большие файлы (1 Гб), так и маленькие (1 Кб). Маленьких файлов может быть... Ну, скажем, 100 000... Соответственно, тут уместно архивирование типа WinRAR. Далее... Необходим доступ к резервной копии в любой момент. Некоторые программы для бэкапа используют резервирование в свой формат, что требует установки софта на каждом компьютере. А это не есть гуд... BAT-файл я могу конфигурировать так, как мне надо. К тому же, к нему имеется быстрый доступ и я могу внести в него изменения за несколько секунд, например добавить новую папку... Я склонялся даже к написанию своей программы на C++, но ввиду того, что среда у меня не установлена, решил сделать BAT'ом. Потом думал что-то подобное написать на Adobe AIR и JavaScript, но опять же - установка Adobe AIR на все компьютеры - не есть гуд. Вот такие дела... Если будут вопросы - могу детальней расписать какой-нибудь пункт ;) ---------------------- Вот, написал согласно инструкциям Foreigner'а, BAT-файл, но выдаёт "Ошибка в синтаксисе"... Код:
::==================================================================================================================================== |
Цитата:
|
Цитата:
Код:
IF NOT DEFINED flag ( |
Iska,
По поводу меток. Два варианта для исследований: Код:
@echo off Код:
@echo off |
А обязательно использовать %%i?
Или вместо i можно использовать f, g и вообще, любую другую букву? Просто с BAT знаком на уровне новичка-любителя... :) И попутно вопрос... В моём случае при использовании проверки IF NOT DEFINED необходимо делать undefine для флага $IS_DEFINED... А как? Ошибка синтаксиса... :( Код:
::==================================================================================================================================== |
Цитата:
Например: Код:
for /f "tokens=1-3" %%а in ("1 2 3") do echo %%а %%б %%в |
Foreigner, спасибо, интересное замечание.
|
frid-karatel, если вы определяете переменную внутри блока кода ( цикл for, if и т.д. ), ограниченного скобками, то повторное использование этой переменной требует установки 'setlocal enabledelayedexpansion' и использование переменных, заключенных в '!' а не в '%'. В вашем батнике это должно быть так, не проверял:
Код:
@ECHO OFF |
Так, ошибку в своём коде исправил - заменил некоторые :: на REM...
Пока выкладывать код не буду - выложу чуть попозже... ;) Попутно возникли ещё вопросы... 1. Как из пути "C:\ParentFolder\ChildFolder\SomeChildFolder\" получить путь "S:\Backup\C\ParentFolder\ChildFolder\SomeChildFolder"? Это необходимо, чтобы соблюсти иерархию... Вообще, требуется в результате иметь "S:\Backup\%COMPUTERNAME%\C\ParentFolder\ChildFolder\SomeChildFolder"... 2. Как получить дату создания самого нового файла в папке? В данном случае, мне надо получить дату самого последнего RAR-файла в папке "S:\Backup". Тут можно попроще что-нибудь, так как имя файла равно дате в формате YYYY-MM-DD 3. Как обнулить (удалить) переменную $IS_MODIFIED? Или она сама обнулится/удалится? Ведь, тогда если в одной папке есть изменения, то переменную надо обнулить/удалить для других папок... Или делать перед циклом SET $IS_MODIFIED=0, а потом проверять не IF NO DEFINED, а IF $IS_MODIFIED=1? :) |
Цитата:
Код:
set "dir=C:\ParentFolder\ChildFolder\SomeChildFolder\" Цитата:
Код:
for /f "tokens=*" %%i in (' dir /b /od /a-d /tc ') do set "newest_file=%%i" Цитата:
Код:
... |
Не получается... Пытаюсь как-то адаптировать, но не могу :)
Foreigner, алгоритм получения даты самого последнего файла не совсем подходит... Дело в том, что в папке с резервными копиями может появиться файл Thumbs.db, у которого дата изменения будет позже, чем у последней копии, вследствие чего будет "неправильность" :) Как узнать дату самую последнюю дату изменения RAR файла в папке? И... почему-то этот код выдаёт слово "Том" вместо даты... Код:
:: >> Поиск изменённых файлов |
Цитата:
Код:
FOR /f "tokens=1" %%i IN ('DIR /s /tw /a-d ^| findstr /b "[0-9]"') DO ( Цитата:
Код:
for /f "tokens=*" %%i in (' dir /b /od /a-d /tc *.rar ') do set "newest_rar=%%i" |
Цитата:
- переход по метке не способен обеспечить прерывание цикла; - обычный IF успешно её заменит и без всякой "путаницы"; - ну и как водится, пара вариантов: |
В бесконечном цикле походу goto вообще не работает, даже goto:eof, только exit
Код:
@echo off |
Всех с Днём Победы! Ура!
В-общем, доделал я то, что хотел... :) Вот результат: Код:
:: =================================================================================================================================== И по одному из них не знаю, как сделать... В данном случае у меня есть список файлов, которые не учитывать при проверке на последнее изменение - это $FILE_EXCLUDE. Хотелось бы иметь возможность исключать не только файлы, но и подпапки. Дело в том, что в некоторых проектах есть HTML-кэш, который изменяется почти каждый час... Соответственно, папку \cache\ и все её подфайлы/подпапки НЕ надо учитывать при проверке на изменение. Как такое дело реализовать? |
Цитата:
|
Цитата:
Код:
@echo off Цитата:
|
Цитата:
Во-вторых, если включить ECHO ON, то видно, что батник на самом деле отрабатывает ВСЕ значения %%i, хотя после GoTo уже вхолостую. Т.е. штатное прерывание циклов FOR не предусмотрено. В-третьих, ошибка "обязательного наличия команды" никак не связана с циклом - это особенность блока, ограниченного круглыми скобками, пример: То, что метку интерпретатор считает незавершенной командой говорит как раз в пользу того, что использование меток в блоке не предусмотрено. Блок считывается интерпретатором целиком и выполняется как одна (кэшированная) команда, в то время как переход по метке является самостоятельной файловой операцией (построчного чтения батника), т.е. может исполняться только между "командами". |
amel27,
Действительно @echo on показателен и это объясняет отказ от выхода из бесконечного цикла, но все равно поведение не совсем объяснимо. Например: Код:
@echo on |
Цитата:
команда, которая "сносит крышу" CMD-интерпретатору: :) P.S. строка должна быть последней в батнике, БЕЗ завершающего CRLF |
Цитата:
|
Ещё один момент - приняв правило "не использовать метки в блоках кода, ограниченных круглыми скобками", мы будем вынуждены принять и его следствие: отказаться от применения в блоках нестандартных комментариев по типу меток "::" - только REM.
|
amel27,
Ну так "::" не комментарий, а метка. С таким же успехом можно: Код:
@echo off |
Цитата:
|
Время: 02:44. |
Время: 02:44.
© OSzone.net 2001-