用于生成特定年份月份,周和周期的文件夹的批处理脚本平日

时间:2017-07-23 21:09:10

标签: batch-file

最后几天我一直在寻找这个问题的答案。有很多关于全年批量文件夹创建的答案,但还不够具体,所以我非常感谢。

所以我希望有这种文件夹结构,如下所示

2017 (for example main folder for year 2017)  
01_JAN....12_DEC (subfolders with names of month )  
01JAN/01_01_SUN, 02_01_MON, 03_01_TUE...etc  (subsub folders with week day name at the end)

如果可能的话也可以在这里包括周数,尽管我会对工作日感到满意,即

01JAN/01_01_SUN-52, 02_01_MON-01, 03_01_TUE-01...09_01_MON-02 etc with weekdays starts with monday
我计划在条形码生产自动化项目中使用它

谢谢! 附: 我得到的最接近的是这个例子,我找到了How do I write a batch script to generate folders for each month, day and year?

3 个答案:

答案 0 :(得分:2)

此批处理文件可以执行您想要的操作。

编辑:我添加了以下修改: 1-从键盘读取年份而不是从参数获取年份。 2-年份文件夹创建在放置批处理文件的同一文件夹中。 3-修复了“第53周”中的一个小错误。

@echo off
setlocal EnableDelayedExpansion

set /P "year=Enter desired year: "

rem Select the base folder
cd "%~P0"

rem Initialize all variables
set i=0
for %%a in (Jan:31 Feb:28 Mar:31 Apr:30 May:31 Jun:30 Jul:31 Aug:31 Sep:30 Oct:31 Nov:30 Dec:31) do (
   for /F "tokens=1,2 delims=:" %%m in ("%%a") do (
      set /A i+=1
      set "month[!i!]=%%m"
      set "dpm[!i!]=%%n"
   )
)
set /A "dpm[2]+=^!(year%%4), d=((year+4799)*1461/4-(year+4899)/100*3/4+1)%%7*3, rot=^!d+((d-15)>>31)+1, week=101+51*rot"
if %d% equ 3 set "week=100"
set "dow=SunMonTueWedThuFriSat"
set "dow=!dow:~%d%!!dow:~0,%d%!"

rem Create the folders
md %year%
cd %year%
for /L %%m in (1,1,12) do (
   set "m=0%%m"
   set "m=!m:~-2!"
   md !m!_!month[%%m]!
   cd !m!_!month[%%m]!
   for /L %%d in (1,1,!dpm[%%m]!) do (
      set "d=0%%d"
      if "!dow:~0,3!" equ "Mon" set /A week+=1 & if !week!!rot! equ 1531 set "week=101"
      md !d:~-2!_!m!_!dow:~0,3!-!week:~1!
      set "dow=!dow:~3!!dow:~0,3!"
   )
   cd ..
)

答案 1 :(得分:1)

可以使用纯批处理和Ritchie Lawrence Batchfunctionlibrary下的MIT License和其他来源发布的几个日期函数的帮助。

  • 此批次将开始日期转换为修改后的朱利安日期
  • 通过添加364或闰年365来计算结束日期。
  • 迭代其间的所有值并生成文件夹名称。
  • MD将创建中间文件夹,只需创建日期文件夹。
  • 批次使用ISO日历周,这意味着第一天/最后一天可能属于上一年/下一年的一周 - 这个不同的年份附加在括号中。

在ramdisk上30秒内创建的示例输出:
EDIT流线型版本,通话次数少,输出相同需要8秒

> tree a:\
A:\
├───2017
│   ├───01_Jan
│   │   ├───01_01_Sun-52(2016)
│   │   ├───02_01_Mon-01
│   │   ├───03_01_Tue-01
│   │   ├───04_01_Wed-01
...
│   │   ├───30_01_Mon-05
│   │   └───31_01_Tue-05
│   ├───02_Feb
│   │   ├───01_02_Wed-05
│   │   ├───02_02_Thu-05
...

这里冗长的批次 (更改变量Base以包含您的基本文件夹):

:: Q:\Test\2017\07\23\SO_45269929.cmd
:: https://stackoverflow.com/questions/45269929/batch-script-to-generate-folders-for-specific-Year-month-and-day
@Echo off&SetLocal EnableExtensions EnableDelayedExpansion
Set "Base=C:\Test\2"
Set "Year=%~1"
If not defined Year Set /P "Year=Enter Year (4 places) yyyy :"

:: To be more efficient get month/day nmaes array
For %%A in (:01:Jan:Mon: :02:Feb:Tue: :03:Mar:Wed:  :04:Apr:Thu:
            :05:May:Fri:  :06:Jun:Sat: :07:Jul:Sun: :08:Aug::
            :09:Sep:: :10:Oct:: :11:Nov:: :12:Dec::
) do for /F "tokens=1-3 delims=:" %%l in ("%%A") do (
    set "MonN[%%l]=%%m"
    set "DayN[%%l]=%%n"
)
Call :DateToMJD %Year% 01 01 StartDate
Call :DateToMJD %Year% 12 31 EndDate

Echo [%date% %time%] Start creating folders for Year %Year%
For /L %%M in (%StartDate%,1,%EndDate%) Do Call :GenDay %%M
Echo [%date% %time%] Done  creating folders for Year %Year%
Goto :Eof

:GenDay
Call :MJDToDate  %1 YY MM DD
Call :DateToWeek %YY% %MM% %DD% yn cw dw
Set "Folder=%Base%\%YY%\%MM%_!MonN[%MM%]!\%DD%_%MM%_!DayN[0%dw%]!-%cw%"
If %YY% neq %yn% Set "Folder=%Folder%(%yn%)"
MD "%Folder%"
Goto :Eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:DateToMJD %yy% %mm% %dd% MJD
::
:: By:   Ritchie Lawrence, 2002-06-15. Version 1.0
::
:: Func: Returns a Modified Julian Day (MJD) from a UTC date.
::       Reference date (day 0) is Wednesday 17th November 1858. For
::       NT4/2K/XP/2003.
:: Args:
::  %1 Year component used to create MJD, 2 or 4 digits (by val)
::  %2 month component used to create MJD, leading zero ok (by val)
::  %3 day of month used to create MJD, leading zero ok (by val)
::  %4 var to receive MJD (by ref)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SetLocal EnableExtensions
Set yy=%1&set mm=%2&set dd=%3
if 1%yy% LSS 200 if 1%yy% LSS 170 (set yy=20%yy%) else (set yy=19%yy%)
Set /a dd=100%dd%%%100,mm=100%mm%%%100
Set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,j=153*m+2
Set /a j=j/5+dd+y*365+y/4-y/100+y/400-2432046
Endlocal&set %4=%j%&Goto :Eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:MJDToDate %MJD% yy mm dd
::
:: By:   Ritchie Lawrence, 2002-06-15. Version 1.1
:: Func:
::  Returns a UTC date from a Modified Julian Day (MJD). Reference
::  date (day 0) is Wednesday 17th November 1858. For NT4/2K/XP/2003.
:: 
:: Args: %1 MJD used to create calEndar date (by val)
::       %2 var to receive Year component, 4 digits (by ref)
::       %3 var to receive month component, 2 digits, 01-12 (by ref)
::       %4 var to receive day of month, 2 digits, 01-31 (by ref)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SetLocal EnableExtensions
Set /a a=%1+2432045,b=4*a+3,b/=146097,c=-b*146097,c/=4,c+=a
Set /a d=4*c+3,d/=1461,e=-1461*d,e/=4,e+=c,m=5*e+2,m/=153,dd=153*m+2
Set /a dd/=5,dd=-dd+e+1,mm=-m/10,mm*=12,mm+=m+3,yy=b*100+d-4800+m/10
(if %mm% LSS 10 set mm=0%mm%)&(if %dd% LSS 10 set dd=0%dd%)
Endlocal&set %2=%yy%&set %3=%mm%&set %4=%dd%&Goto :Eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:DateToWeek %yy% %mm% %dd% yn cw dw
::
:: By:   Ritchie Lawrence, Updated 2002-11-20. Version 1.1
::
:: Func: Returns an ISO 8601 Week date from a calEndar date.
::       For NT4/2000/XP/2003.
:: 
:: Args: %1 Year component to be converted, 2 or 4 digits (by val)
::       %2 month component to be converted, leading zero ok (by val)
::       %3 day of month to be converted, leading zero ok (by val)
::       %4 var to receive Year, 4 digits (by ref)
::       %5 var to receive calEndar week, 2 digits, 01 to 53 (by ref)
::       %6 var to receive day of week, 1 digit, 1 to 7 (by ref)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SetLocal EnableExtensions
Set yy=%1&set mm=%2&set dd=%3
if 1%yy% LSS 200 if 1%yy% LSS 170 (set yy=20%yy%) else (set yy=19%yy%)
Set /a dd=100%dd%%%100,mm=100%mm%%%100
Set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,Jd=153*m+2
Set /a Jd=Jd/5+dd+y*365+y/4-y/100+y/400-32045
Set /a y=yy+4798,Jp=y*365+y/4-y/100+y/400-31738,t=Jp+3,Jp=t-t%%7
Set /a y=yy+4799,Jt=y*365+y/4-y/100+y/400-31738,t=Jt+3,Jt=t-t%%7
Set /a y=yy+4800,Jn=y*365+y/4-y/100+y/400-31738,t=Jn+3,Jn=t-t%%7
Set /a Jr=%Jp%,yn=yy-1,yn+=Jd/Jt,yn+=Jd/Jn
if %Jd% GEQ %Jn% (set /a Jr=%Jn%) else (if %Jd% GEQ %Jt% set /a Jr=%Jt%)
Set /a diff=Jd-Jr,cw=diff/7+1,wd=diff%%7,wd+=1
if %cw% LSS 10 set cw=0%cw%
Endlocal&set %4=%yn%&set %5=%cw%&set %6=%wd%&Goto :Eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

答案 2 :(得分:1)

由于内在的日期功能,PowerShell的答案要紧凑得多 这里没有几周:

$Base = 'D:\Test'
$Year = 2017
$StartDate = Get-Date -Year $Year -Month 1  -Day 1
$EndDate   = Get-Date -Year $Year -Month 12 -Day 31
$DateRange = New-TimeSpan -Start $StartDate -End $EndDate
0..$DateRange.Days|ForEach-Object {
    MD $($Base+$StartDate.AddDays($_).ToString('\\yyyy\\MM_MMM\\dd_MM_ddd'))
}