Архивирование каталога
Здравствуйте!
Помогите, пожалуйста, со следующими вопросами. 1. Есть каталог Src и каталог Dst. Требуется создать батник, который будет запускаться периодически, т.е. от случая к случаю, и который будет добавлять архивы ВСЕХ каталогов, включая их подкаталоги, из Src в Dst с именами архивов, совпадающими с именами каталогов первого уровня из Src. То есть, после отработки такого батника, в Dst должны создаться все несуществующие там архивы с именами, совпадающими с именами каталогов первого уровня из Src. Архивы в Dst могут быть как *.rar, *.zip, *.7z и пр. одновременно. Важны лишь сами имена без их архивного расширения. В целях ускорения работы такого батника при его повторных запусках, хотелось бы, чтобы при наличии в каталоге Dst архивов (*.rar, *.zip, *.7z и пр.) с именами каталогов из Src, эти каталоги из Src повторно в Dst не переархивировались. То есть, если запустить такой батник в случае, когда в Dst уже имеются все имена архивов, совпадающие (без учёта архивного расширения типа .rar, .zip, .7z и пр.) c именами каталогов первого уровня из Src, то такой батник ничего не должен создавать или перепаковывать. При этом должно быть допустимым наличие в Dst прочего содержимого - как файлов, так и папок, которые вообще не имеют отношения к именам из Src. 2. Если предположить частный случай по первому вопросу - имена каталогов первого уровня в Src находятся в формате даты YYYYMMDD, хотелось бы отдельным батником установить реальные даты создания/изменения этих каталогов в соответствии с их именами. Время не важно. Буду признателен за помощь. |
Чересчур дурная лабораторка.
|
UserX,
лабораторка?
Код:
@Echo Off Цитата:
Есть, например, папка 20180925. Что должно происходить в батнике и какой результат его работы? |
Цитата:
|
megaloman, огромное Вам спасибо за Ваш отклик без излишней демонстрации своего превосходства над оппонентом.
Сейчас опробую Ваш батничек и отпишусь. Цитата megaloman: Есть, например, папка 20180925. Что должно происходить в батнике и какой результат его работы? » Да просто эта эта папка 20180925 должна получить дату своего создания и изменения 25.09.2018, и всё. :) Iska, и вам спасибо за то, что оказались неравнодушны. Ибо, как сказал Юлиус Фучек: "Бойся равнодушных! Это с их молчаливого согласия совершается всё зло на земле!" Очевидно, вас бояться не следует. |
Цитата:
|
Цитата megaloman:
Что значит получить? » Это значит, что дата создания этой папки не совпадает с датой, определяемой именем папки. Хотелось бы это устранить и привести в соответствие. megaloman, проверил Ваш батник. Немного его изменил под себя и всё ПРЕВОСХОДНО сработало. Огромное Вам спасибо! ---------------------------- @Echo Off cls Set "Src=C:\111\Src\*.*" Set "Dst=C:\111\Dst" Set Arc="C:\Program Files\WinRar\Rar.exe" a -r -ep1 -dh -m5 -s -rr5p -ts+ -y Set "Ext=rar" If Not Exist "%Dst%" Md "%Dst%" FOR /D %%d IN ("%Src%") DO ( If Not Exist "%Dst%\%%~nxd.*" (Echo "%%d" &%Arc% "%Dst%\%%~nxd.%Ext%" "%%d\*.*") ) ---------------------------- Если не использовать ключ -ep1, то в архиве сохраняется весь путь C:\111\Src\Cat_name Ключ -ep1 подавил сохранение в архиве лишнего пути, правда, несколько больше, чем хотелось бы. :) А без этого ключа задача как-то решается? |
megaloman, а я понял так, что дату создания и дату последней модификации каталога надо задавать по содержащейся в его имени дате (время при этом несущественно).
|
Цитата megaloman:
То есть, если папка 20180925 изменялась 20180929, то её надо переименовать? 20180925-->20180929 » Не-не, вообще ничего переименовывать не нужно. Просто в результате обычного копирования были утрачены исходные даты создания папок. Но эти исходные даты создания папок являются именами этих папок. Так что нужно взять папку с именем 20180925 и (можно даже ничего не проверяя) установить ей дату 20180925. Соответвственно, папка с именем 20180929 должна получить дату 20180929. То есть, после отработки, батник должен привести дату создания файла в соответствие с его именем. Извините, пожалуйста, что не слишком понятно ставил вопрос. |
Цитата:
А так, Если не использовать ключ -ep1? (остальные ключи не трогал и смысл их наизусть не помню - Ваша ответственность). Но, ИМХО, m5 -это чересчур, иногда архив получается больше, чем m3, а время радикально увеличивается
Код:
@Echo Off Цитата:
|
Цитата:
Огромное Вам спасибо! В батниках Вы не просто мегаломэн, а настоящий мегалодон! :up |
Цитата:
Ещё никогда Штирлиц не был так близок к провалу :).
|
Iska,
Придумал достаточно идиотский способ, на вложенные файлы/папки он не действует
Код:
@Echo Off |
megaloman, это работает!! Вы - просто супер. :clapping:
|
megaloman, мне невероятно понравилась Ваша идея с маской.
С такой идеей мою частную задачу (лабораторку) можно обобщить на более общую задачу. Допустим, есть группа файлов (папок), имена которых связаны с датой их создания. Например: <Info1>2018<delimeter>10<delimeter>??<Info2> где <Info1> и <Info2> (вместе с символами < и >, которые используются лишь для улучшения читабельности) - некоторые тексты, являющиеся необязательной частью имени файла. <Info1> и/или <Info2> - произвольный текст, который может и отсутствовать; <delimiter> - символ-разделитель между годом, месяцем и днём в имени файла. Может быть не один, а может и вовсе отсутствовать; Например, если указывается маска: Set "Mask=File_2018-10-??_Original" то подразумевается, что данная маска будет читаться так: "Группа всех файлов (каталогов), начинающаяся со слова "File_" и заканчивающаяся словом "_Original" за весь октябрь месяц 2018 года. Теперь сама задача. Очень хотелось бы модифицировать Ваш последний скрипт, таким образом, чтобы по указанной маске из каталога Src выбирался ТОЛЬКО ОДИН самый последний по сортирумому имени файл и, если архива с таким именем нет в каталоге Dst, то он туда архивировался. То есть из приведённой маски: File_2018-10-??_Original из Src должен выбраться только один файл с именем "File_2018-10-31_Original" (или другой последний, если за 31.10.2018 ничего нет) и архивироваться в Dst при отсутствии в нём архва с таким именем. Оно, конечно, в приведённой маске указание направления сортировки с Ascending на Discending могло бы вместо последнего октябрьского файла 2018 года выбрать первый октябрьский файл 2018 года, но это уже может оказаться перебором с моей стороны. Я извиняюсь, если вдруг подкидываемые мною "лабораторки" стали выглядеть как некоторая наглость со стороны человека, который сам только теоретизирует, а делать за него должен кто-то другой. Ничего такого в мыслях не было. Просто подкинутая в Вашем скрипте идея маски меня совершенно свела с ума своим великолепием и очень захотелось её практически применить с максимальной эффективностью. |
Код:
@Echo Off |
megaloman, да, с каталогами в папке Src это теперь прекрасно работает!
А можно ли сделать так, чтобы в каталоге Src могли быть не только вложенные папки, к которым будет применима такая маска, но и просто файлы, к которым будет применяться та же самая маска? То есть, различия между папкой или файлом в каталоге Src для архивирования быть не должно, а маска должна одинаково относиться и к файлам, и к папкам. Таким образом архивироваться в каталог Dst будут или файл, или папка из Src, в зависимости от того, чьё имя старше с точки зрения даты, являющейся частью имени. Или такое возможно только либо-либо, то есть, либо в каталоге Src будут папки и тогда файлы будут игнорироваться, либо файлы, но тогда будут игнорироваться каталоги? Я ещё раз извиняюсь за наглость. :unsure: |
можно сделать так, чтобы в каталоге Src могли быть не только вложенные папки, к которым будет применима такая маска, но и просто файлы, к которым будет применяться та же самая маска
Код:
@Echo Off |
megaloman, Вы это сделали, и это работает!!
Огромное Вам спасибо! Вы - лучший. Поделюсь с Вами мыслями. Конечно, делать мешанину из файлов и папок в каталоге не совсем здОрово, но раз даже это проходит, значит, для Src, состоящего только из каталогов или только из файлов это будет работать точно, поскольку задача решена Вами в самом общем виде. Потому просторы для этого решения открываются просто безграничные. Я пока не могу их даже полностью осмыслить до самого конца. Практически, Вы сделали гипотезу батеньки Пуанкаре реальностью! :up:clapping: PS Вот осмыслю до конца и поглядим, какие новые проблемы создаст это решение. :) |
megaloman, произошло некоторое осмысление. :)
Проверил работу скрипта при очень разной маске и с весьма разнообразным содержимым каталога Src. Даже при пустой маске, т.е.: Set "Mask=" на мой взгляд работает правильно. Пустая маска полностью соответствсует маске *.* Т.е. Set "Mask=" полностью эквивалентна Set "Mask=*.*" И это, на мой взгляд, вполне логично. Однако, коль скоро эти два варианта работают идентично, можно ли попросить Вас о модификации Вашего последнего скрипта таким образом, чтобы при задании пустой маски, т.е. при указании: Set "Mask=", как исключение, скрипт работал несколько иначе. А именно, если маска пустая, чтобы архивировались из каталога Src в каталог Dst не самый последний, а ВСЕ папки и ВСЕ файлы, архивов которых ещё нет в Dst. Тогда этот один скрипт станет универсальным и заменит собой (и даже расширит) скрипт из первой задачи. Спасибо! |
если маска пустая, чтобы архивировались из каталога Src в каталог Dst не самый последний, а ВСЕ папки и ВСЕ файлы, архивов которых ещё нет в Dst
Код:
@Echo Off |
megaloman, Всё превосходно работает!
Но я, нагло используя плоды Вашего труда, немного переформулировал свою же задачу, дабы уже не было никаких ограничений по маске, и маска оставалась только маской без всяких посторонних смыслов. Для того, чтобы не грузить маску иным, нехарактерным для неё смыслом, я решил ввести в скрипт дополнительный параметр "Mode". Если установить Set "Mode=1", то получим однофайловый режим, а при любых других значениях Mode, например, если установить Set "Mode=0", получим режим архивации всех файлов из Src, архивов которых ещё нет в Dst. Ну, и ещё добавил режим сортировки, дабы в однофайловом режиме архивировался либо первый, либо последний файл или каталог в зависимости от заданного режима сортировки. Set "Ascending=" прямая сортировка - архивируется последний каталог или файл по маске. Set "Ascending=-" обратная сортировка - архивируется первый каталог или файл по маске. Естественно, ничего моего в полученном скрипте нет, всё полностью сделано из Вашего последнего скрипта. Просто он теперь полностью решает вместе и первую и вторую задачи по маске. Прошу Вас, как настоящего профессионала, на всякий случай, посмотреть и проверить - не напорол ли я каких-либо косяков при "модернизации" Вашего превосходного исходника. Ну, или, может можно сделать как-то изящнее, поскольку изначально задача мною озвучивалась совсем иначе. Модернизированный батник
@Echo Off cls ;Rem Mode must be set to 1 for OneFileMode or any value (0) for AllFilesMode Set "Mode=1" ;Rem Set "Mode=0" Set "Src=C:\111\Src" Set "Dst=C:\111\Dst" Set "Mask=??10??" ;Rem Маска всех октябрьских файлов и каталогов. ;Rem Mask - Mask for catalogs or files in Src. ;Rem Set "Ascending=" ;Rem "Ascending=" прямая сортировка - архивируется последний каталог или файл по маске Set "Ascending=-" ;Rem Set "Ascending=-" обратная сортировка - архивируется первый каталог или файл по маске Set Arc="C:\Program Files\WinRar\WinRar.exe" a -r -ma4 -m5 -rr5p -ts+ -y Set "Ext=rar" Pushd "%Src%" || (Echo Folder not Found "%Src%" &Pause &Exit /B 2) If Not Exist "%Dst%" Md "%Dst%" || (Echo Folder not Created "%Dst%" &Pause &Exit /B 3) If "%Mode%"=="1" GoTo :OneFile Set /A Err=1 For /F "usebackq delims=" %%d IN (`2^>nul Dir "%Src%\%Mask%" /B /O:%Ascending%N`) DO Set /A Err=0 &Call :OutArc "%%d" GoTo :End :OneFile Set "Name=" For /F "usebackq delims=" %%d IN (`2^>nul Dir "%Src%\%Mask%" /B /O:%Ascending%N`) DO Set "Name=%%d" If "%Name%"=="" (Echo File or Folder not Found "%Src%\%Mask%" &Pause &Exit /B 1) Call :OutArc "%Name%" Set /A Err=%ErrorLevel% :End Popd pause Exit /B %Err% :OutArc If Not Exist "%Dst%\%~1.*" (Echo "%Src%\%~1" &%Arc% "%Dst%\%~1.%Ext%" "%~1") Exit /B И ещё пара вопросов: 1) Команда "pause" в скрипте несёт какую-то иную цель, кроме сообщения о том, что батник выполнился и для продолжения нужно нажать любую клавишу? Имеется ввиду, удаление этой команды из скрипта не отразится на чём-либо ещё в его работе? Просто мой опыт говорит, что порой что-то, на первый взгляд, очевидное таковым не всегда является в реалии. Поэтому, лучше лишний раз уточнить. 2) Как правильнее подавить вывод сообщений о результатах работы этого батника, если использовать его в заданиях Шедулера Виндовс? Ставить после каждой команды "> Nul" ? Или это делается как-то однократно в самом начале батника? Вообще, что, на Ваш взгляд, имело бы смысл подправить в синтаксисе батника при его использовании в задании Шедулера? |
Вот оптимизированный вариант ориентированный на планировщик
Код:
@Echo Off 2. Если использовать батник в заданиях планировщика, то, наверное, надо иметь лог-файл. Если не надо, закомментируйте выделенные строки. 3. Для настройки работы команды Dir лучше использовать явным образом ключи. Делаем команду Dir /? и изучаем ключи и присваиваем нужный список переменной DirKey. В частности, Set "DirKey=/O:-N /A:D" даст алфавитную сортировку в обратном порядке и включит в рассмотрение только папки. 4. Маску оставил как есть. В принципе можно легко ввести специальную переменную. Но не увидел большого смысла. 5. Я использую Winrar.exe, подозреваю, он работает быстрее. Можно, конечно, использовать rar.exe, например: Set Arc="C:\Program Files\WinRar\Rar.exe" a -r -dh -m3 -s -rr5p -ts+ -y и подавить его вывод %Arc% "%Dst%\%~1.%Ext%" "%~1" >nul 6. Цитата:
|
Цитата:
Цитата:
Решил-таки оставить свою переменную Mode, поскольку без неё не будет работать произвольная маска выбора ВСЕХ файлов по заданной маске при их архивации, а будет иметься ввиду только маска *.* (сам ведь такую заказывал :) ) Собственно, только ради этого смысла и была введена переменная Mode Огромное Вам спасибо за проделанную работу, представленный мастер-класс, в результате которого мною была получена бесценная информация. Спасибо Вам ещё раз. |
megaloman, Предложенный Вами последний оптимизированный батник перестал работать так, как он работал ранее и так, как мне было нужно. Изменить его так, чтобы он остался оптимизмрованным и при этом работал так, как он работал до последней оптимизации мне не удалось.
Всё-таки, мне очень нужно ввести переменную Mode, поскольку она позволяет работать с заданной маской в любом из двух режимов: в режиме AllFilesMode (с заданной маской) и в режиме OneFileMode (тоже с заданной маской). То, что приведено ниже, сейчас работает так, как нужно, но оно не оптимизировано и нет вывода логов. Пожалуйста, помогите оптимизировать для планировщика приведённый батник, в котором указываются режимы Mode 0 и Mode 1. Заранее большое спасибо. Рабочий, но неоптимизированный батник
Код:
@Echo Off |
Цитата:
Здесь вариант с так любимой Вами переменной Mode
Код:
@Echo Off |
megaloman, опробовал Ваш последний батник.
Что интересно - результат его работы в режиме Mode=0 (AllFilesMode) зависит от значения DirKey То есть, в указанном режиме Mode=0 (AllFilesMode) при DirKey=/O:-N и DirKey=/O:N результаты работы в каталоге Dst существенно между собой различаются, хотя, по логике дел, они должны бы быть одинаковы. Если, конечно, я ничего не упускаю из вида. Правильная, на мой взгляд, работа в режиме Mode=0 (AllFilesMode) достигается только в случае установки в команде Dir ключа прямой сортировки, т.е. при DirKey=/O:N. Это, видимо, значит, что в режиме Mode=0 (AllFilesMode) от DirKey нужно вообще оказаться и явно устанавливать ключ прямой сортировки для Dir, т.е. /O:N. С учётом изложенного, модифицированная версия полностью работающего батника, кажется наконец-то, обретает завершённый вид: Незначительная модификация
Код:
@Echo Off Посмотрите, пожалуйста. |
Цитата:
Дело Ваше. (1.)Клиент всегда прав. (2.)Если клиент не прав, смотри (1.) Успехов! PS. Обратите внимание, что в посте #18 для одного файла выбирается последний в списке Dir файл, а в постах #23, #26 выбирается первый. Вот тут и имеет значение /O:N в старых вариантах и /O:-N в последних вариантах. |
Цитата:
В этом одном режиме результаты работы батника в папке Dst при "SetKey=/O:N" и "SetKey=/O:-N" могут получиться совершенно разные. Но я вполне допускаю, что при некоторых вариантах маски эти результаты могут быть и совершенно идентичными. Но разве результаты работы сами по себе не является реальностью? Я ведь эти резульаты работы никак не подтасовывал и не пытался ввести Вас в заблуждение. С чем тут можно соглашаться или не соглашаться? Меня и самого это удивило. Но факт есть факт, вне зависимости от того, согласен ли кто угодно с ним или нет. Цитата:
Цитата:
Да и как такое возможно - "сделать некорректное тестирование"? По-моему, тестирование не может быть корректным или некорректным. Оно может быть просто тестированием. Готов выложить Вам примерное содержимое папки Src, которое в режиме с установленным режимом Set /A Mode=0 (то есть, если установлен режим всех файлов по заданной маске), даёт разные результаты в папке Dst по количеству и видам созданных архивов при изменении ключа сортировки в Dir c прямого на обратный, чтобы вы смогли лично в этом убедиться. Выложить свой тест? |
Ключи:
Set /A Mode=0 Set "Mask=??10??.*" Dir исходной папки Src
Код:
Содержимое папки C:\111\Src Dir результата в Dst при /N:O
Код:
Содержимое папки C:\111\Dst Dir результата в Dst при /N:-O
Код:
Содержимое папки C:\111\Dst |
Цитата:
Спасибо Вам за всю проделанную Вами работу и за Ваше долготерпение, которое Вы проявили к оппоненту, несмотря ни на что. Удачи Вам! |
UserX,
Цитата:
При анализе наличия архива по маске Файл.* получим соответствие с Файл.jpg.*=Файл.* с ключом /O:-N Гарантировать, что при ключе /O:N не получится еще какой-нибудь непредсказуемый пропуск, не берусь. Чтобы результат был предсказуем (работа батника надежнее),то: Либо считаем, что все архивы имеют расширение %Ext% (в нашем случае Rar), тогда исправление: Код:
:OutArc Либо надо перечислить все возможные расширения архивов
Код:
@Echo Off И вааще, смесь файлов/папок с одинаковыми именами и разными расширениями может дать неожиданный результат при любых алфавитных сортировках даже при отборе 1 файла с маской с расширением .* Удалите в Вашем наборе папку 181027 и, в зависимости от ключа сортировки, будете иметь или 181028.rar или 181030.jpg.rar Так что при смеси кони/люди (файлы/папки c одинаковыми именами, но разными расширениями) откажитесь от маски с расширением .* и используйте только жестко определённое расширение. |
Цитата:
То есть, Ваш батник с честью выдержал все мои корявые тесты и ни разу не подвёл и не обманул моих ожиданий. Единственное, я ещё раз хочу настоятельно уточнить, что в строке, касающейся прохождения проверки, что установлен режим Mode==0, я явно задаю прямое направление сортировки команды Dir ключом /O:N, т.е. я изменил одну Вашу строку в исходнике так (выделено жирным): If %Mode%==0 For /F "usebackq delims=" %%d IN (`2^>nul Dir "%Src%\%Mask%" /B /O:N`) DO (Set /A Err=0 &Call :OutArc И это принципиально для получения правильного результата работы батника при хаосе в каталоге Src. Что же касается мешанины в каталоге Src, так она специально и создавалась таковой для тестирования. В реалии у меня такого бардака в Src, конечно же, нет. Но ведь проверить-то было нужно! :) Считаю, что правильно написанная програма справляется со всеми вариантами, что, собственно, и продемонстрировал написанный Вами батник. |
UserX, Лог-файл создаётся? Путь к нему указан правильно? Я получил аналогичный результат, когда указал кривой путь к лог-файлу
Цитата:
|
Цитата:
Сейчас поправил, и всё прекрасно заработало. Извините меня, пожалуйста, за невнимательность и ложную тревогу. :( Собственно, почему я переименовал Log в LogFile. Хотел ещё ввести у себя параметр Log, типа: Set "Log=Yes" для того, чтобы вставить проверку - создавать или нет log-файл. Да что-то в моих неумелых руках не задалось... :) |
Цитата:
Скрытый текст
— там имена возвращаются в порядке создания записей каталога. |
Цитата:
Как же так? Ведь это же хаос какой-то! Ну, по умолчанию - ладно. Что там Dir выдаёт по умолчанию известно только ей, хотя, да, я ещё помню, что в fat32 командой Dir по умолчанию выдаются имена в порядке их создания. Но ведь если явно указан ключ сортировки, то почему он не работает?? Я не понимаю... |
Цитата:
Цитата:
Цитата:
Неверным является только одно предположение — что по умолчанию (в случае отсутствия параметра /o, отсутствия переменной окружения DIRCMD, отсутствия в содержимом переменной окружения DIRCMD параметра /o) команда dir возвращает имена-расширения файлов и каталогов из оглавления каталога в лексикографическом порядке. Это не так. |
Цитата:
|
Время: 08:38. |
Время: 08:38.
© OSzone.net 2001-