Войти

Показать полную графическую версию : [решено] Создание папок по имени и перемещение файлов


xan08
03-07-2019, 13:12
Добрый день. Помогите алгоритмом решения, примером, готовым решением. Задача обстоит так следующим образом.
В папке D:\backup множество файлов по типу D_Воскресенье_56_my-files_backup.2019-06-09-10-00_00 Есть задача раскладывать их в папку "Неделя 27" -> ''D_Воскресенье" и .т.д. Папки должны генерироваться автоматически в зависимости от того какая неделя. Нашел скрипт который создает папку беря за основу часть из названия файла. А вот как прикрутить создание папки с номером недели и перемещать файлы в актуальную неделю не могу найти решения.


@echo off
setlocal

set "basename=."
for /F "tokens=2* delims=_" %%a in ('dir /B /A-D ^| sort /R') do (
set "filename=D_%%a"
setlocal EnableDelayedExpansion
for /F "delims=" %%c in ("!basename!") do if "!filename:%%c=!" equ "!filename!" (
set "basename=!filename!"
md "!basename!"


)

move "!filename!_%%b" "!basename!"
for /F "delims=" %%c in ("!basename!") do (
endlocal
set "basename=%%c
)
)

megaloman
03-07-2019, 17:22
D_Пятница_56_my-files_backup.2019-06-09-10-00_00 »
Как должна называться папка, куда надо переместить этот файл?
2019-06-09 (если это гггг-мм-дд) это воскресенье 23 недели.

xan08
03-07-2019, 19:16
Как должна называться папка, куда надо переместить этот файл?
2019-06-09 (если это гггг-мм-дд) это воскресенье 23 недели. »

Извиняюсь. Не тот день указал. В данном примере файл должен переместиться в папку D:\backup\Неделя 23\D_воскресенье

megaloman
04-07-2019, 00:15
xan08, @Echo Off
cls
Set "BoxIn=Z:\Box_In"
Set "MaskIn=*_backup.20*.*"

Set "BoxOut=D:\backup"

FOR %%f IN ("%BoxIn%\%MaskIn%") DO Set "FF=%%~nxf" &Call :Out "%%f" "%%FF:*.=%%" "%BoxOut%"
Pause
GoTo :Eof

:Out
Set "A=%~2"
Set "A=%A:~8,2% %A:~5,2% %A:~0,4%"
Call :NweekInYear %A% "NWeek"
Set "NWeek=0%NWeek%"
Set "NWeek=%NWeek:~-2%"
Call :NdayInWeek %A% "DWeek"
rem FOR /F "tokens=%DWeek% delims= " %%i IN ("Понедельник Вторник Среда Четверг Пятница Суббота Воскресенье") DO Set "DWeek=%%i"
FOR /F "tokens=%DWeek% delims= " %%i IN ("Понедельник Вторник Среда Четверг Пятница Суббота Воскресенье") DO Set "DWeek=%DWeek%_%%i"
If Not Exist "%~3\Неделя %NWeek%\D_%DWeek%" Md "%~3\Неделя %NWeek%\D_%DWeek%"
>nul Move /Y %1 "%~3\Неделя %NWeek%\D_%DWeek%\"
Exit /B

rem Номер недели в году дд мм гггг имя_переменной
:NweekInYear
SetLocal
Call :JdayGcal 01 01 %3 "N1"
Call :NdayInWeek 01 01 %3 "W1"
Call :JdayGcal %1 %2 %3 "N2"
EndLocal &Set /A %~4=(%N2%-%N1%+6+%W1%)/7
Exit /B

rem Юлианский день по григорианскому календарю дд мм гггг имя_переменной
:JdayGcal
SetLocal
Set "D=0%1" &Set "M=0%2"
Set /A D=1%D:~-2%-100,M=1%M:~-2%-100
Set /A A=(14-%M%)/12, Y=%3+4800-A, M=%M%+12*A-3
EndLocal &Set /A %~4=(%D%+(153*%M%+2)/5+365*%Y%+%Y%/4-%Y%/100+%Y%/400-32045)
Exit /B

rem Номер дня в неделе дд мм гггг имя_переменной
:NdayInWeek
SetLocal
Set "D=0%1" &Set "M=0%2"
Set /A D=1%D:~-2%-100,M=1%M:~-2%-100
Set /A i=(%3-1901)*365 + (%3-1901)/4 + %D% + (!(%3 %% 4))*(!((%M%-3)^&16))
EndLocal &Set /A %~4=(%i%+(%M%-1)*30+2*(!((%M%-7)^&16))-1+((65611044^>^>(2*%M%))^&3))%%7+1
Exit /B

megaloman
04-07-2019, 08:28
xan08, Если в имени Ваших файлов маска именно такая, как Вы указали, то есть:
D_Имядня_номернедели_траляляляля, то решение многократно проще:@Echo Off
cls
Set "BoxIn=Z:\Box_In"
Set "BoxOut=D:\backup"

FOR /F "usebackq tokens=1,2,3* delims=_" %%i IN (`2^>nul Dir "%BoxIn%\D_*_*_*20*.*" /B /A:-D`) DO (
If Exist "%BoxIn%\%%i_%%j_%%k_*20*.*" (
If Not Exist "%BoxOut%\Неделя %%k\%%i_%%j" Md "%BoxOut%\Неделя %%k\%%i_%%j"
>nul 2>&1 Move /Y "%BoxIn%\%%i_%%j_%%k_*20*.*" "%BoxOut%\Неделя %%k\%%i_%%j"
)
)
Pause
GoTo :Eof@Echo Off
cls
Set "BoxIn=Z:\Box_In"
Set "BoxOut=D:\backup"

Set /A Понедельник=1, Вторник=2, Среда=3, Четверг=4, Пятница=5, Суббота=6, Воскресенье=7

FOR /F "usebackq tokens=1,2,3* delims=_" %%i IN (`2^>nul Dir "%BoxIn%\D_*_*_*20*.*" /B /A:-D`) DO (
If Exist "%BoxIn%\%%i_%%j_%%k_*20*.*" (
Call 2>nul Md "%BoxOut%\Неделя %%k\%%i%%%%j%%_%%j"
Call >nul 2>&1 Move /Y "%BoxIn%\%%i_%%j_%%k_*20*.*" "%BoxOut%\Неделя %%k\%%i%%%%j%%_%%j\"
)
)
Pause
GoTo :Eof
Забыл напомнить: батники сохранять в 866 кодировке

xan08
05-07-2019, 06:00
rem Номер дня в неделе дд мм гггг имя_переменной
:NdayInWeek
SetLocal
Set "D=0%1" &Set "M=0%2"
Set /A D=1%D:~-2%-100,M=1%M:~-2%-100
Set /A i=(%3-1901)*365 + (%3-1901)/4 + %D% + (!(%3 %% 4))*(!((%M%-3)^&16))
EndLocal &Set /A %~4=(%i%+(%M%-1)*30+2*(!((%M%-7)^&16))-1+((65611044^>^>(2*%M%))^&3))%%7+1 »

Спасибо megaloman! Первый скрипт устраивает полностью, за исключением номера дня в названии папки D_5_Пятница, можно ли это поправить? Не могли бы вы расписать кратенько, что происходит в этой секции? 1%D:~-2% гуглиться плохо, был бы признателен если ткнете ссылкой где можно почитать.
xan08, Если в имени Ваших файлов маска именно такая, как Вы указали, то есть:
D_Имядня_номернедели_траляляляля, то решение многократно проще: »
Спасибо, возможно получится изменить формат имени в бэкапе, а так в названии нет номера недели, это что то вроде порядкового номера.

megaloman
05-07-2019, 11:28
Первый скрипт устраивает полностью, за исключением номера дня в названии папки D_5_Пятница, можно ли это поправить? »В коде всё уже содержится. Минимальная поправка: былоrem FOR /F "tokens=%DWeek% delims= " %%i IN ("Понедельник Вторник Среда Четверг Пятница Суббота Воскресенье") DO Set "DWeek=%%i"
FOR /F "tokens=%DWeek% delims= " %%i IN ("Понедельник Вторник Среда Четверг Пятница Суббота Воскресенье") DO Set "DWeek=%DWeek%_%%i"
сделайте FOR /F "tokens=%DWeek% delims= " %%i IN ("Понедельник Вторник Среда Четверг Пятница Суббота Воскресенье") DO Set "DWeek=%%i"
rem FOR /F "tokens=%DWeek% delims= " %%i IN ("Понедельник Вторник Среда Четверг Пятница Суббота Воскресенье") DO Set "DWeek=%DWeek%_%%i"
Кстати, оказывается понятие "номер недели в году" не так просто, как я по наивности полагал. Я считаю, что первый день недели - это неделя с 1 января. Если Вас это устраивает, то всё в порядке.кратенько, что происходит в этой секции »Я взял готовые коды, с которыми когда-то давно столкнулся, не берусь вспомнить, где. Оформил их в виде процедур, чтобы использовать по мере надобности и не изобретать велосипед. Можно найти исходные формулы, но лень.
Вот пример использования этих процедур@Echo Off
cls
Call :JdayGcal 01 01 2019 "N1"
Call :JdayGcal 05 07 2019 "NX"

Set /A NY=%NX%-%N1%+1
Echo Номер дня в году %NY%

Call :NdayInWeek 05 07 2019 "NW"
Echo Номер дня недели %NW%
Pause
GoTo :Eof

rem Юлианский день по григорианскому календарю дд мм гггг имя_переменной
:JdayGcal
SetLocal
Set "D=0%1" &Set "M=0%2"
Set /A D=1%D:~-2%-100,M=1%M:~-2%-100
Set /A A=(14-%M%)/12, Y=%3+4800-A, M=%M%+12*A-3
EndLocal &Set /A %~4=(%D%+(153*%M%+2)/5+365*%Y%+%Y%/4-%Y%/100+%Y%/400-32045)
Exit /B

rem Номер дня в неделе дд мм гггг имя_переменной
:NdayInWeek
SetLocal
Set "D=0%1" &Set "M=0%2"
Set /A D=1%D:~-2%-100,M=1%M:~-2%-100
Set /A i=(%3-1901)*365 + (%3-1901)/4 + %D% + (!(%3 %% 4))*(!((%M%-3)^&16))
EndLocal &Set /A %~4=(%i%+(%M%-1)*30+2*(!((%M%-7)^&16))-1+((65611044^>^>(2*%M%))^&3))%%7+1
Exit /B
На основе этих процедур решал и Вашу задачу. Увы, прямую формулу для определения номера недели в году не нашел.

YuS_2
05-07-2019, 11:53
Кстати, оказывается понятие "номер недели в году" не так просто, как я по наивности полагал. »
Зависит от инструмента...
powershell
get-date -uf %V #number of 01-53
get-date -uf %U #number of 00-52

Iska
05-07-2019, 12:15
Зависит от инструмента... »
Зависит от региона :). Потому во многих инструментах и есть параметр, какую именно неделю следует трактовать, как первую в году.

YuS_2
05-07-2019, 12:40
Зависит от региона »
Никак не зависит. Существует международный стандарт ISO 8601, кроме того ГОСТ ИСО 8601 (межгосударственный стандарт), которые определяют четко и ясно, какая неделя считается первой в году, а какая крайней.

Потому во многих инструментах и есть параметр, какую именно неделю следует трактовать, как первую в году. »
Самодеятельность чистейшей воды, если существует. :)

Iska
05-07-2019, 13:25
Никак не зависит. Существует международный стандарт ISO 8601, кроме того ГОСТ ИСО 8601 (межгосударственный стандарт), которые определяют четко и ясно, какая неделя считается первой в году, а какая крайней. »
Коллега, Вы путаете стандарты и существующие реалии.

YuS_2
05-07-2019, 13:45
Вы путаете стандарты и существующие реалии. »
Почему путаю? Реалии они, возможно, и не такие, какие должны быть, но:
Если кому-либо, захочется плясать от собственной печки, то тут, конечно, ничем не поможешь, это понятно.
Но если уж использовать в ПО понятия, которые стандартизированы, то зачем изобретать велосипеды? Надо просто заглянут в документацию и следовать тому, что в ней написано. Имхо. :)

Iska
05-07-2019, 13:52
YuS_2, дело в том, что реалии существовали задолго до появления стандартов и какого-либо ПО в принципе.

YuS_2
05-07-2019, 15:09
дело в том, что реалии существовали задолго до появления стандартов и какого-либо ПО в принципе. »
Но это же не значит, что нам теперь надо расстояние измерять в вёрстах, длину в аршинах, локтях, вершках, перстах и т.п.? :)
Нет, можно конечно и по юлианскому календарю жить... но, имхо, это равнозначно плаванию против течения... непродуктивно, то бишь.

Iska
05-07-2019, 15:29
YuS_2, знаете, это не мне надо рассказывать. Вон, те же Штаты по сю пору длину меряют не метрами, объёмы — не литрами, первая неделя в году у них всё еще начинается с первого января, да и сама неделя всё ещё начинается у них с воскресенья. И ладно бы они одни…

YuS_2
06-07-2019, 05:53
Вон, те же Штаты по сю пору длину меряют не метрами, объёмы — не литрами, первая неделя в году у них всё еще начинается с первого января, да и сама неделя всё ещё начинается у них с воскресенья. »
Это понятно, спорить тут не о чем, наверное. Естественно, что не везде и не повсеместно, все проблемы стандартизации мер и весов решены на все сто...
Проблемы различных летоисчислений, учета времени и прочего, связанного с календарями, как раз, следствие отсутствия международных стандартов. А англосаксы, всегда были ведь впереди планеты всей с навязчивыми и навязываемыми идеями... а все нормальные и вменяемые, рано или поздно, принимают международные стандарты (во всяком случае, по достаточно важным аспектам жизни), чем сильно упрощают жизнь себе и другим...
И да, мы ведь живем в реалиях стран проживания, правильно? А межгосударственный стандарт, который создан на основе международного, принят ещё с 2004г., причем принят не одной страной, что в нем самом и записано. Поэтому считаю, что не имеет смысла оглядываться на футо-мили-пинты, а жить по тем самым стандартам, которые приближены к международным. Так надежнее и проще, имхо.

megaloman
06-07-2019, 10:33
YuS_2, я не знаком с аргументацией, почему по ГОСТ ИСО 8601-2001 "ПРЕДСТАВЛЕНИЕ ДАТ И ВРЕМЕНИ" первая неделя года должна содержать первый четверг года, для каких отраслей это критично,я не берусь судить.
Речь о другом: есть клиент с поставленной задачей, которому надо как-то структурировать бэкапы. И, в данном случае, способ нумерации недель я бы отдал на откуп клиенту, он должен определиться, зачем ему это нужно. Интуитивно мне ближе "американский" способ нумерации недель- неделя с 1 января первая, но, когда принимался ГОСТ, очевидно, были серъезные основания делать по иному.

mwz
06-07-2019, 11:22
первая неделя года должна содержать первый четверг года »

Потому что в такой "неделе" больше чем половина недели: 4 дня минимум.

"Почему от понедельника до субботы — пять дней, а от субботы до понедельника — два?"

megaloman
06-07-2019, 11:57
mwz, зачпм вообще такое нужно? Имхо, чтобы избежать двойного счета одной недели в разных годах. Иначе коллизия: число недель за несколько лет меньше чем сумма количества недель за каждый год в периоде. Наверное, с точки зрения заключения договоров, где сроки исчислены в неделях, это важно. С точки зрения хранения бэкапов - не думаю, что это удобно. То есть, возвращаясь к теме, клиенту виднее

YuS_2
06-07-2019, 12:11
Интуитивно мне ближе "американский" способ нумерации недель- неделя с 1 января первая, но, когда принимался ГОСТ, очевидно, были серъезные основания делать по иному. »
Ок, можно и с аргументацией:
1. пусть будет 1 января - первая неделя...
2. 1 января - допустим суббота.
Внимание вопросы:
1. Сколько недель в году?
2. Какая неделя в году последняя?
3.1 01.01, суббота - это какая неделя?
3.2 31.12, пятница - это какая неделя?
3.3 пятница и суббота - это одна неделя или две?
как-то так... как будут в "американском" стандарте звучать ответы?

Международным стандартом описываются именно такие вот вопросы, вот такими ответами:
1. В году 52 или 53 недели.
2. Предыдущая первой неделе следующего года.
3.1 Последняя неделя предыдущего года.
3.2 Последняя неделя уходящего года.
3.3 Одна, единственная неделя.

первая неделя года должна содержать первый четверг года, для каких отраслей это критично,я не берусь судить. »
Первая календарная неделя года может включать до трех дней предыдущего календарного года. Последняя календарная неделя календарного года может включать до трех дней следующего года.
Четверг взят как промежуточное звено, то бишь среднее значение календарной недели. Там же, из тех же соображений, есть ещё и упоминание 4 января, по которому тоже можно определять первую календарную неделю календарного года.
В каких отраслях это критично - я тоже не возьмусь судить, но во всяком случае, никаких разночтений этот стандарт не допускает. И это правильно, независимо от области применения... если этого не описывать в стандарте, то может возникнуть вольная трактовка подсчета недель и какие изощренные умы могли бы этим воспользоваться и в каких целях, можно только догадываться.




© OSzone.net 2001-2012