Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Создание папок по имени и перемещение файлов (http://forum.oszone.net/showthread.php?t=341147)

xan08 03-07-2019 13:12 2877914

Создание папок по имени и перемещение файлов
 
Добрый день. Помогите алгоритмом решения, примером, готовым решением. Задача обстоит так следующим образом.
В папке 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 2877968

Цитата:

Цитата xan08
D_Пятница_56_my-files_backup.2019-06-09-10-00_00 »

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

xan08 03-07-2019 19:16 2877993

Цитата:

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

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

megaloman 04-07-2019 00:15 2878064

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 2878072

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

С точки зрения алфавитной сортировки при просмотре папок, ИМХО, имена папок с днём недели выгодно дублировать номером дня в неделе, например: D:\backup\Неделя 23\D3_среда, D:\backup\Неделя 23\D7_воскресенье
Код:

@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 2878247

Цитата:

Цитата megaloman
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% гуглиться плохо, был бы признателен если ткнете ссылкой где можно почитать.
Цитата:

Цитата megaloman
xan08, Если в имени Ваших файлов маска именно такая, как Вы указали, то есть:
D_Имядня_номернедели_траляляляля, то решение многократно проще: »

Спасибо, возможно получится изменить формат имени в бэкапе, а так в названии нет номера недели, это что то вроде порядкового номера.

megaloman 05-07-2019 11:28 2878276

Цитата:

Цитата xan08
Первый скрипт устраивает полностью, за исключением номера дня в названии папки 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 января. Если Вас это устраивает, то всё в порядке.
Цитата:

Цитата xan08
кратенько, что происходит в этой секции »

Я уже писАл, что использовал известные приёмы для работы с датами
Я взял готовые коды, с которыми когда-то давно столкнулся, не берусь вспомнить, где. Оформил их в виде процедур, чтобы использовать по мере надобности и не изобретать велосипед. Можно найти исходные формулы, но лень.
Вот пример использования этих процедур
Код:

@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 2878280

Цитата:

Цитата megaloman
Кстати, оказывается понятие "номер недели в году" не так просто, как я по наивности полагал. »

Зависит от инструмента...
powershell
Код:

get-date -uf %V #number of 01-53
get-date -uf %U #number of 00-52


Iska 05-07-2019 12:15 2878285

Цитата:

Цитата YuS_2
Зависит от инструмента... »

Зависит от региона :). Потому во многих инструментах и есть параметр, какую именно неделю следует трактовать, как первую в году.

YuS_2 05-07-2019 12:40 2878290

Цитата:

Цитата Iska
Зависит от региона »

Никак не зависит. Существует международный стандарт ISO 8601, кроме того ГОСТ ИСО 8601 (межгосударственный стандарт), которые определяют четко и ясно, какая неделя считается первой в году, а какая крайней.

Цитата:

Цитата Iska
Потому во многих инструментах и есть параметр, какую именно неделю следует трактовать, как первую в году. »

Самодеятельность чистейшей воды, если существует. :)

Iska 05-07-2019 13:25 2878303

Цитата:

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

Коллега, Вы путаете стандарты и существующие реалии.

YuS_2 05-07-2019 13:45 2878307

Цитата:

Цитата Iska
Вы путаете стандарты и существующие реалии. »

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

Iska 05-07-2019 13:52 2878310

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

YuS_2 05-07-2019 15:09 2878319

Цитата:

Цитата Iska
дело в том, что реалии существовали задолго до появления стандартов и какого-либо ПО в принципе. »

Но это же не значит, что нам теперь надо расстояние измерять в вёрстах, длину в аршинах, локтях, вершках, перстах и т.п.? :)
Нет, можно конечно и по юлианскому календарю жить... но, имхо, это равнозначно плаванию против течения... непродуктивно, то бишь.

Iska 05-07-2019 15:29 2878323

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

YuS_2 06-07-2019 05:53 2878409

Цитата:

Цитата Iska
Вон, те же Штаты по сю пору длину меряют не метрами, объёмы — не литрами, первая неделя в году у них всё еще начинается с первого января, да и сама неделя всё ещё начинается у них с воскресенья. »

Это понятно, спорить тут не о чем, наверное. Естественно, что не везде и не повсеместно, все проблемы стандартизации мер и весов решены на все сто...
Проблемы различных летоисчислений, учета времени и прочего, связанного с календарями, как раз, следствие отсутствия международных стандартов. А англосаксы, всегда были ведь впереди планеты всей с навязчивыми и навязываемыми идеями... а все нормальные и вменяемые, рано или поздно, принимают международные стандарты (во всяком случае, по достаточно важным аспектам жизни), чем сильно упрощают жизнь себе и другим...
И да, мы ведь живем в реалиях стран проживания, правильно? А межгосударственный стандарт, который создан на основе международного, принят ещё с 2004г., причем принят не одной страной, что в нем самом и записано. Поэтому считаю, что не имеет смысла оглядываться на футо-мили-пинты, а жить по тем самым стандартам, которые приближены к международным. Так надежнее и проще, имхо.

megaloman 06-07-2019 10:33 2878423

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

mwz 06-07-2019 11:22 2878428

Цитата:

Цитата megaloman
первая неделя года должна содержать первый четверг года »

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

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

megaloman 06-07-2019 11:57 2878431

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

YuS_2 06-07-2019 12:11 2878435

Цитата:

Цитата megaloman
Интуитивно мне ближе "американский" способ нумерации недель- неделя с 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 Одна, единственная неделя.

Цитата:

Цитата megaloman
первая неделя года должна содержать первый четверг года, для каких отраслей это критично,я не берусь судить. »

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


Время: 15:10.

Время: 15:10.
© OSzone.net 2001-