Get date from file name and check age - batch-file

I will have a variable that will be equal to anything from 1-7, which will represent 1 day old and so on. I need to find a file that is the same age in days as that variable.
For example
set "age=4"
// code to find the file OR folder that is 4 days old
It's worth noting that I need to get the filename of this file

Here, try this:
#echo off
setlocal
set age=4
set /a maxage=age+1
:: For files that are %age% days old or older, set a variable
for /f "delims=" %%I in ('forfiles /d -%age%') do (
set "fileArr[%%~snxI]=%%~fI"
)
:: for files that are %age% + 1 days old or older, unset variable
for /f "delims=" %%I in ('forfiles /d -%maxage%') do (
set "fileArr[%%~snxI]="
)
:: Get values of all remaining fileArr variables
for /f "tokens=1,* delims==" %%I in ('set fileArr') do echo(%%J
As you can see from the comments, first the script gets all files %age% days old or older, and sets a variable. To make the variable name unique and to be able to index it later, the variable name contains the short filename, simulating an associative array. Next, it unsets those variables which are %age% + 1 days old or older, then outputs what's left.
No painful date math is needed. forfiles handles the computation. If you needed age-by-minutes computation, admittedly that gets a little more complicated; but forfiles handles math by day just fine.

I found a much easier soloution:
ROBOCOPY "D:\file-backups\%ThisUser_Username%\Server"^
"%ThisService_WorkingDirectory%#DayZ_Epoch_Server\Addons"^
"dayz_server_*.pbo"^
/minage:%ThisService_filerestoreage%^
/maxage:%ThisService_filerestoreage%

In batch, as soon as you get the date of modification which corresponds to the age, (thus %DATE% - %AGE%), you can use the ~t modifier in a parameter expansion to get the age of the file.
Note that if you have PowerShell on your system (and you really should because it's preinstalled since Win7, cf comments) you can use it to do the date calculation easily.
Hence, a script that does what you want (with the parameter being %age% which you can replace with a command-line parameter for example) :
set age=4
for /f "delims=|" %%i in ('powershell.exe -Command "Get-Date -Format dd/MM/yyyy -Date ([DateTime]::Today.AddDays(-%age%))"') do set age_date=%%i
echo Files modified %age% days ago (the %age_date%) are :
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=|" %%f in ('dir /b') do (
set file_date=%%~tf
if "!file_date:~0,10!"=="%age_date%" (echo %%f)
)
For a pure-batch script to get the date to replace the powershell call (say for legacy versions), you could slightly modifiy the code from here : http://www.powercram.com/2010/07/get-yesterdays-date-in-ms-dos-batch.html , even though that would get very ugly.
In contrast, unix-like systems have a tool for this, see man find, which is more user-friendly.
find /path/to/parent/directory -daystart -atime $age
atime : File was last accessed n*24 hours ago
$age without leading + or - : find exactly age of $age*24 hours (as opposed to less or equal, or superior or equal)
daystart :
Measure times (for -amin, -atime, -cmin, -ctime, -mmin, and
-mtime) from the beginning of today rather than from 24 hours
ago
You can use mtime instead of atime for modified date instead of creation date.

Related

How to create a subfolder based on current date? [duplicate]

This question already has answers here:
How do I get current date/time on the Windows command line in a suitable format for usage in a file/folder name?
(30 answers)
How to create a folder with name as current date in batch (.bat) files
(25 answers)
How to get the date format in windows batch file as 'yyyymmdd'?
(1 answer)
Batch command date and time in file name
(15 answers)
What does %date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2% mean?
(2 answers)
Closed 4 years ago.
I want to use a command to copy the entire contents of a folder (including subfolders) to a different drive.
For example:
robocopy c:\evernote\ e:\evernote\<datestamp>\
where <datestamp> is a new folder whose name represents the current date in this format:
2018_05_21
So, the target "evernote" folder will contain a series of subfolders, one folder for each date. Each subfolder will contain the files that were copied from source to target on that date.
For me, I don't think it matters if the command is copy, robocopy, xcopy, or whatever. However, I believe that robocopy is most up-to-date, and therefore most likely to be of future use to me.
BTW: To keep this simple, there's no need to allow for different time zones, and no need for "automation" - I will run the BAT file myself, and add automation later.
Thanks.
Because you're using, and happy to use, RoboCopy for the copying process, here's a method which also uses it to determine the date:
#Echo Off
Set "sd=C:\EverNote"
Set "dd=E:\EverNote"
Set "ds="
If Not Exist "%sd%\" Exit /B
For /F "Tokens=1-3Delims=/ " %%A In ('RoboCopy/NJH /L "\|" Null'
) Do If Not Defined ds Set "ds=%%A_%%B_%%C"
If Not Defined ds Exit /B
RoboCopy "%sd%" "%dd%\%ds%" /E
You can edit the locations in lines 2 and 3, (but do not remove the existing doublequotes or introduce your own, and do not include trailing backslashes with those folder names)
When writing in Batch, you should be able access the environment variable %date%.
This is a string of the current date.
You can try to use echo %date% to see what it looks like, and then split and recombine the string, so it fits your need.
Beware though, that the format of the string is dependent on how you set your datetime settings on your computer. If you change to use another format on the computer, the format of %date% will also change.
To generate a date in a certain format without worring about localization settings you can use this:
#echo off
for /f %%# in ('wMIC Path Win32_LocalTime Get /Format:value') do #for /f %%# in ("%%#") do #set %%#
:echo %day%
:echo %DayOfWeek%
:echo %hour%
:echo %minute%
:echo %month%
:echo %quarter%
:echo %second%
:echo %weekinmonth%
:echo %year%
if %day% lss 10 set day=0%day%
if %month% lss 10 set month=0%month%
set f_date=%year%-%month%-%day%
echo %f_date%
The %date% variable format depends on the settings in the control panel and it's value will be different on different machines. For more ways to get a formatted date you can check this
This script uses PowerShell to get the datestamp in the desired format:
#Echo off
for /f "usebackqdelims=" %%D in (
`powershell -Nop -C "(Get-Date).ToString('yyyy_MM_dd')"`
) Do Set "datestamp=%%D"
Echo robocopy c:\evernote\ e:\evernote\%datestamp%\
Sample output:
robocopy c:\evernote\ e:\evernote\2018_06_02\

robocopy command to move file based on created date

I have files in a folder 'FILEPATH', each file has different created date and modified date(modified date is less than created date).
I want to delete the files with created date greater than 10days. I used below command but it works on modified date.
ROBOCOPY %FILEPATH% %DUMPFOLDER% /move /minage:10
del %DUMPFOLDER% /q
On some forums its written that minage refers to created date but it's referring to modified date while executing. Am I doing something wrong here? Or is there any other alternate.
Unfortunately, there's no easy way to do this. The only commands of which I'm aware that can deal with file creation dates are dir /t:c and wmic datafile. There could be others, but there are none that simplify performing date math as forfiles or robocopy do.
Since date math in batch is cumbersome anyway, in this situation it makes sense to borrow from another runtime environment -- PowerShell, for example, or VBScript or JScript. The Windows Scripting Host FileSystemObject's File Object has properties for DateCreated, DateLastAccessed, and DateModified. With JScript, getting a file's age based on its DateCreated property is simply a matter of JavaScript Date() arithmetic.
Here, salt this .bat script to taste:
#if (#CodeSection == #Batch) #then
#echo off
setlocal
set "FILEPATH=c:\path\to\whatever"
set "age=10"
for %%I in ("%FILEPATH%\*") do (
call :getAge result "%%~fI"
setlocal enabledelayedexpansion
if !result! gtr %age% (
echo %%~nxI created !result! days ago and should be deleted
rem del "%%~fI"
) else (
echo %%~nxI is new ^(created !result! days ago^)
)
endlocal
)
goto :EOF
:getAge <return_var> <filename>
for /f "delims=" %%I in ('cscript /nologo /e:Jscript "%~f0" "%~2"') do set "%~1=%%I"
goto :EOF
#end
// JScript portion
var fso = WSH.CreateObject('scripting.filesystemobject'),
created = fso.GetFile(WSH.Arguments(0)).DateCreated,
age = new Date() - created;
WSH.Echo(Math.floor(age / 1000 / 60 / 60 / 24));
If you want something simpler, you could employ wmic datafile and get the first 8 digits of get creationdate like this cat does, but his solution doesn't take into account time of day. Such a method might inappropriately delete files that are 9 days, 23 hours old. Then there's also the problem of calculating days across new months. The JScript method above tests file age based on the current moment, rather than based on midnight; and will handle spanning months, years, and leap years with no conscious effort.

Compare current date with file modified date in batch file

I have a requirement to create a batch file and that should work in windows 2003 server.
I have source folder "c:\Source" and destination folder "c:\Destination".
I want to check all the file modified dates in source folder:
If the file modified date is less than current date then that file will move into destination folder
Otherwise, do nothing.
Note: as my server is production server so, I am unable to install Resource kit and robocopy.exe. The only way is write the batch script.
Robocopy and forfiles are not working in Windows2003 server.
Update
Since you have forfiles on your server, this is easy. To check for files older than 1 day old, just use forfiles /D -1. For files over 2 days old, /D -2.
forfiles /D -2 /M *.log /P C:\Source /C "cmd /c move #file c:\Destination"
Enter forfiles /? in a console window for full syntax.
Original answer
Consider revising your requirement. Instead of saying "If file modified date is less than the current date", you should say, "If file modified date does not equal current date". That absolves you from having to do date math, and makes your task profoundly simpler. After all, the last modified date is not going to be a date in the future, right?
After that, it's a simple matter of scraping today's date from %date% and comparing it with the date from each file's %%~tX substitution property in a for loop. Type help for in a console window and see the last two pages for more information about this syntax.
I don't think there will be any locale date formatting issues with this. As long as your system's %date% variable is in the format of dayOfWeek Date and %%~tX is formatted as Date Time etc. then this script should work regardless of whether you handle dates locally as MM/DD/YYYY or YYYY/MM/DD or DD/MM/YYYY or something else. I hope.
#echo off
setlocal enableextensions
set "source=c:\Source"
set "destination=c:\Destination"
:: store today's date in %today%
for /f "tokens=2" %%I in ('echo %date%') do set "today=%%I"
for %%I in ("%source%\*") do (
rem :: scrape MM/DD/YYYY from %%~tI
for /f %%a in ('echo %%~tI') do (
rem :: compare the two dates
if "%%a" neq "%today%" (
echo %%~nxI: %%a does not equal %today%. Moving.
>NUL move /y "%%~fI" "%destination%"
) else (
echo %%~nxI: %%a equals %today%. Skipping.
)
)
)

Add 1 year to the current date in a batch file

Hi couldnt find anything here to help out with this one.
My company has a set of client folders that require a set of subfolders to be created at the end of each financial year. This is required to be a 2 digit representation of the year (ie - 14 Folder1 [for 2014] and so on).
I have a batch file that creates the folders every year, but have to modify the year every time. I am looking to schedule an auto mated solution, but i am stuck trying to add 1 additional year to the date. (as the folders need to be created at the end of the financial year, not calender year).
I am looking for a way to add 1 year to the current date. Here is my batch file so far. Any ideas anyone?
set YEAR= %DATE:~-2% + %DATE:~-2%
for /f "delims=|" %%s in ('dir /ad/b') do md "%%s\%YEAR% Folder1"
for /f "delims=|" %%s in ('dir /ad/b') do md "%%s\%YEAR% Folder2"
for /f "delims=|" %%s in ('dir /ad/b') do md "%%s\%YEAR% Folder3"
Like this :
set /a YEAR=%DATE:~-2% + 1
set /a YEAR=1%DATE:~-2%+1
set YEAR= %DATE:~-2%%YEAR:~-2%
This is assuming that you want 1415 for the 2014-2015 financial year.
Are you aware that your construct will yield a Space before the string? Spaces are significant in string-assignments - on both sides of the =.
It's safer to use
set "YEAR=%DATE:~-2%%YEAR:~-2%"
for instance - the rabbit's ears in this format ensure that trailing spaces are omitted (that can cause chaos)

Create bat or script file to delete files

I would like to know how to create a bat file which on its first run would store the system date and on subsequent run delete a particular file 30 days later.I think if a bat file can be created that would store system date on its first run and the second bat files reads the first file for the date would be better.But how?
As #devio commented, PowerShell is definitely more fully featured: PowerShell Quick Reference
If it has to be a Batch file, this reference explains most commands.
I love powershell, and it is certainly more powerful than batch files, but for this it shouldnt really matter what you use, so if you're comfortable with your batch files you should be able to stick with them.
The only way you'll be able to later recover that date is to store it somewhere (or have your task running the whole time which is unrealistic - think reboots among other things)
You could write the deletion date to the registry or a text file or somewhere else that is 'known', but then you need to have something else running to check 'if its time to act'.
I'd be inclined to just create a scheduled task for the delete during the original script so that I wouldn't have to check up on it. You could even have the delete script you've scheduled clean up the task when it's done.
You could use something like a windowscripting host vb script or js script file. Also scripting languages such as php, python or perl would allow you to do something like this easily and possibly give you much greater flexibility than a shell script.
It's going to take a while to answer this one, but here's the first thing to suggest.
When you want to have a single .BAT (or .CMD) which does something and also does something later based on the first something, one can use the "flag parameter" technique. For example, in a script which accepts a wildcarded list of files to manipulate one could do as follows:
::foo.cmd
#echo off
if %1#==# goto fail
set f=%1
if %1==! goto inner
for %%x in (%f%) do cmd /c %0 ! %%x
goto done
:inner
set f=%2
echo do something with %f%
goto done
:fail
echo %0 {wildcard}
:done
The script is actually written such that it can be called anything, and it will call itself (using %0).
Now how to do date arithmetic is going to take some time to figure out. I hope that much at least gets you started in the right direction.
my setup after after completion of installation would run a bat file(once) that should get the system date(install date) and store in a text file.the main program would be called by another batch file that would read the text file every time for the date assisting it to delete particular files after "N" number of days referencing the install date in the text file.
HI MARK BRACKETT,
when I run batch1 the date is MM\DD\YYYY.But when I run batch2 the startdate is DD and the startmonth is also DD.The final equation is if rundate==nowdate execute command,it should be rundate=>nowdate,cause if pc not switched on rundate.secondly months with 31days the rundate would 31st next month
VBScript, PowerShell, or C# (I use CS-Script to run my C# scripts) would be much cleaner - but sometimes I enjoy a little batch file challenge.
So - this is for 1 month from the current date and time, but it gives you the idea. To actually figure 30 days, I suspect you'd need about 50 lines of IF statements. Or, a single external EXE to calculate it for you.
I think there's a cleaner way to use SET itself to split out the date parts, which would cut this down by about 3 lines - but I don't recall the syntax ATM.
Batch1
ECHO %DATE% > start.txt
Batch2
: Get start date
FOR /F "tokens=1* delims= " %%i IN (start.txt) DO set startDate=%%j
FOR /F "tokens=1,2 eol=/ delims=/ " %%i IN ('echo %startDate%') DO set startMonth=%%i
FOR /F "tokens=1,2 delims=/ eol=/" %%i IN ('echo %startDate%') DO set startDay=%%j
FOR /F "tokens=2,3 delims=/ " %%i IN ('echo %startDate%') DO set startYear=%%j
: Get run month and day as YYYY-MM-DD
SET /A runMonth=%startMonth% + 1
IF %runMonth% LEQ 10 SET runMonth=0%runMonth%
SET runDay=%startDay%
SET runYear=%startYear%
SET runDate=%runYear%-%runMonth%-%runDay%
: Get current month and day as YYYY-MM-DD
FOR /F "tokens=1* delims= " %%i IN ('echo %DATE%') DO set nowDate=%%j
FOR /F "tokens=1,2 eol=/ delims=/ " %%i IN ('echo %nowDate%') DO set nowMonth=%%i
FOR /F "tokens=1,2 delims=/ eol=/" %%i IN ('echo %nowDate%') DO set nowDay=%%j
FOR /F "tokens=2,3 delims=/ " %%i IN ('echo %nowDate%') DO set nowYear=%%j
SET nowDate=%nowYear%-%nowMonth%-%nowDay%
: Compare
IF %nowDate% GEQ %runDate% ECHO Delete!
Note that this doesn't handle year changes appropriately (it'll delete on the year change).

Resources