2

My requirement is to create folder with year ("Y" + yyyy, for example Y2019) and a sub folder inside that folder with month and year (yyyymm, for example 201904) and then I need to move my file inside that folder.

I have analyzed and found code to get year and month from current date only.

%DATE%

I have successfully retrieved the file created date using the following command, but could not able to found a way to get only year and month from this.

dir /T:C filename

enter image description here

Please provide a way to get year and month from a date retrieved from a file.

s p
  • 789
  • 1
  • 6
  • 23
  • It's possible to get the output of `dir /T:C` with a [`for /F` loop](https://ss64.com/nt/for_cmd.html); however, the date/time format returned by `dir` is locale-dependent, so I suggest to take a look at these posts: [How to get standardized date/time stamp of file or dir. in pure batch scripting?](https://stackoverflow.com/q/33248149) and [How to escape both comma and closing parenthesis in WHERE clause of WMIC?](https://stackoverflow.com/q/37198153) Of course you have to use property `CreationDate` instead of `LastModified`... – aschipfl Jul 25 '19 at 11:27

2 Answers2

1

Given your example dir cmd, you appear to want to move a file to a folder based on the year and month the file was written.

Using your exact method od finding the date is one option, of 4 which come to mind quickly. (A For loop, Dir, Where, and Forfiles all come to mind)

To split out the date to be usble from any of those cmd options you could save the cmd output of the date into a variable and manipulate it manually by cutting it into aspecific subsections, or by using a FOR /F loop to tokenize (cut it into peices) the portions of the date using the delimiters you show in your output.

However, to capture that into a variable from Dir will nessessitate parsing in a For /F loop, in which case we can tokenize the date directly instead of creating a temp variable anyway.

For these reasons and others (such as being able to run both in a cmd script or in CLI with the same logic) I prefer using theFor /F loop.

This can be pasted into the Command line directly:

@FOR /F "Tokens=2-3 delims=- " %A IN ('
  dir  /A-D /T:C "C:\Sethu\LICENSE"
  ^| Find /I "LICENSE"
') DO @(
  MD "C:\Sethu\Y%B\%B%A\"
  MOVE /Y "C:\Sethu\LICENSE" "C:\Sethu\Y%B\%B%A\LICENSE"
)

Or if you prefer to have a CMD Script which you could edit where the path and files are you can use this:

@(
  SETLOCAL EnableDelayedExpansion
  ECHO OFF
  SET "_Path=C:\Sethu"
  SET "_File=LICENSE"
)

FOR /F "Tokens=2-3 delims=- " %%A IN ('
  dir /A-D /T:C "%_Path%\%_File%"
  ^| Find /I "%_File%"
') DO (
  IF NOT EXIST "%_Path%\Y%%B\%%B%%A\" (
    MD "%_Path%\Y%%B\%%B%%A\"
  )
  MOVE /Y "%_Path%\%_File%" "%_Path%\Y%%B\%%B%%A\%_File%"
)

As noted above, I am using the FOR /F loop to parse the output from DIR and split the date into two tokens with %%A holding the month and %%B holding the Year.

I then use these tokens to create the directory and sub directory MD "%_Path%\Y%%B\%%B%%A\" and do the move of the file to that directory.


The above examples work for one specific file, below examples work for multiple files

The above examples work for one specific file, below examples work for multiple files and allow combinations of fully defined file names and paths, and paths with filenames that include wildcards to match multiple files.

At the CLI (CMD Prompt)

FOR %a IN (
  "C:\Sethu\LICENSE"
  "C:\Some\Folder\thisthat.txt"
  "C:\Another\Folder\*.xls*"
) DO @(
  FOR /F "Tokens=2-3 delims=/ " %A IN (
    "%~ta"
  ) DO @(
    MD "%~dpaY%B\%B%A\"
    MOVE /Y "%~fa" "%~dpaY%B\%B%A\%~nxa"
  )
)

IN a CMD Script:

@(
  SETLOCAL EnableDelayedExpansion
  ECHO OFF
)

FOR %%a IN (
  "C:\Sethu\LICENSE"
  "C:\Some\Folder\thisthat.txt"
  "C:\Another\Folder\*.xls*"
) DO @(
  FOR /F "Tokens=2-3 delims=/ " %%A IN (
    "%%~ta"
  ) DO @(
    MD "%%~dpaY%%B\%%B%%A\"
    MOVE /Y "%%~fa" "%%~dpaY%%B\%%B%%A\%%~nxa"
  )
)
PAUSE
Ben Personick
  • 3,074
  • 1
  • 22
  • 29
  • @Stephan LOL! Wow I cant believe I did that instead of changing to a FOR loop or using a Find on the Dir! Well, Distracted is as distracted does I suppose! What a fantastically simple mistake! :) Thanks for pointing it out Stephan, quick fix to be sure, but still. – Ben Personick Jul 25 '19 at 22:02
0

I would recommend leveraging in conjunction with for this task.

You can do that from a :

@For /F %%A In (
    'PowerShell -NoP "(GCI LICENSE).CreationTime.ToString('Yyyyy\\yyyyMM')" 2^>NUL'
)Do @RoboCopy . %%A LICENSE /Mov>NUL 2>&1

Or directly from :

For /F %A In ('PowerShell -NoP "(GCI LICENSE).CreationTime.ToString('Yyyyy\\yyyyMM')" 2^>NUL')Do @RoboCopy . %A LICENSE /Mov>NUL 2>&1

If, based upon the comments, you decide to instead use the modification time, simply change CreationTime to LastWriteTime.

Compo
  • 36,585
  • 5
  • 27
  • 39