s visu
s visu

Reputation: 11

How to move certain files from one folder to another new folder based on the time stamp in the file name?

I just want to create a bat file to move log files which are older than 60 days into another new folder which should be created dynamically with time stamp.

Format of the log files will be "Filename_YYYYMMDD".

kindly let me know ,how to implement this functionality via BAT file?

Please suggest if there are any other ways to implement this functionality.

Upvotes: 0

Views: 243

Answers (2)

dbenham
dbenham

Reputation: 130839

Working with date and time is a pain in Windows batch. I have written a hybrid JScript/batch utility called getTimestamp.bat that makes it easy to work with dates and time. It is pure script that will run on any modern Windows machine from XP forward. My batch solution below uses getTimestamp.bat.

Here is a solution, without any documentation. It uses the date embedded within the name. It ignores the last modified attribute of the file:

@echo off
setlocal disableDelayedExpansion
call getTimestamp -od -60 -f {yyyy}{mm}{dd} -r cutoff
for /f "eol=: delims=" %%F in (
  'dir /b /a-d *_*.log | findstr /ir ".*_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\.log"'
) do (
  set "file=%%F"
  set "name=%%~nF"
  setlocal enableDelayedExpansion
  set "dt=!name:~-8!"
  if !dt! lss %cutoff% (
    if not exist !dt!\ md !dt!
    move "!file!" !dt! >nul
  )
  endlocal
)

And here is the exact same code, fully documented:

@echo off

:: Outside of a code block, lines beginning with :: are comments
:: Within a code block, comments are enclosed within %= coment =%
:: Note that %=comment=% style comments cannot containn : or %

:: This solution uses a FOR loop to process file names, and names may contain !
:: FOR variable values are corrupted if they contain ! and are expanded with
:: delayed expansion enabled. So start out with delayed expansion disabled.
setlocal disableDelayedExpansion

:: Establish the cutoff by subtracting 60 days from the current date
call getTimestamp -od -60 -f {yyyy}{mm}{dd} -r cutoff

:: This outer FOR /F loop iterates the result of a command.
:: The chosen command lists the candidate files, one per line.
:: EOL=: guards against unlikely event of file name beginning with ;
:: Names that begin with EOL character will be skipped. Default EOL is ;
:: No file name can contain : so it is a safe EOL value to use.
:: DELIMS= nothing prevents name from being chopped up.
for /f "eol=: delims=" %%F in (

  %= The DIR /B option gives a bare listing consisting only of file name.   =%
  %= The DIR /A-D option screens out folder names.                          =%
  %= The DIR file mask gives an inexact file name filter.                   =%
  %= The result is piped to FINDSTR with a regular expression that exactly  =%
  %= specifies the file name filter.
  'dir /b /a-d *_*.log | findstr /ir ".*_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\.log"'

) do (

  %= Save the full name and extension of the file =%
  set "file=%%F"

  %= Get the base name of the file (without extension) =%
  set "name=%%~nF"

  %= Delayed expansion required to access a variable =%
  %= within the same block that defined it.          =%
  setlocal enableDelayedExpansion

  %= get the date string from the last 8 characters of name  =%
  set "dt=!name:~-8!"

  %= Verify that the file date string is less than the cutoff date =%
  if !dt! lss %cutoff% (

    %= Create the target folder if it does not already exist =%
    if not exist !dt!\ md !dt!

    %= Move the file to the target folder.                  =%
    move "!file!" !dt! >nul
  )

  %= SETLOCAL must be ended if used within a loop because stack is limited =%
  endlocal
)

Upvotes: 1

npocmaka
npocmaka

Reputation: 57252

Not tested (assumed that the files have no extensions like in the question)(also assumed that the timestamp should be taken from the file name):

@echo off

forfiles /m *_*  /d -60  /c  "cmd /e:on /v:on /c for /f 0x22tokens=1,2 delims=_0x22 %%a in (0x22@file0x22) do (md 0x22%%~b0x22>nul 2>&1 & move 0x22%%~a_%%~b 0x22%%~b )"

Also can be executed from command prompt:

forfiles /m *_*  /d -60  /c  "cmd /e:on /v:on /c for /f 0x22tokens=1,2 delims=_0x22 %a in (0x22@file0x22) do (md 0x22%~b0x22>nul 2>&1 & move 0x22%~a_%~b 0x22%~b )"

Upvotes: 1

Related Questions