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\
Related
I want to create a batch file which when clicked will create a folder with the name 12012016.
I tried with the command
mkdir "E:\Meru\Work\Trace Reports\%date:~6,4%%date:~3,2%%date:~0,2%
But its creates with the name 20160112.
Please help
This question implies that you have not tried to understand what is going on with this command...
Split in part: mkdir will create a directory with the name you have given.
The name you have given is build together using a fixxed string, you decided to use E:\Meru\Work\Trace Reports\ and three substrings from the system variable %date%.
Substring in batch works like this: %variable_name:~last character NOT to use,number of characters you need%. In your case it takes the year first, then the month and at last the day. You would just simply change the parts from %date:~6,4%%date:~3,2%%date:~0,2% to %date:~3,2%%date:~0,2%%date:~6,4%.
Notice!
The variable %date% has a different value based on the system settings for the time format. An alternative is the command wmic os get localdatetime which I covered in another answer here that will always have the same output format no matter what the settings are.
If you have read this ==> Windows batch file redirect output to logfile with date/time
You can be able to do like this one :
#echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
set datestamp=%dt:~0,8%
set timestamp=%dt:~8,6%
set YYYY=%dt:~0,4%
set MM=%dt:~4,2%
set DD=%dt:~6,2%
set HH=%dt:~8,2%
set Min=%dt:~10,2%
set Sec=%dt:~12,2%
set stamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%
echo stamp: "%stamp%"
pause
echo datestamp: "%datestamp%"
pause
echo timestamp: "%timestamp%"
pause
set MyDateVar=%MM%%DD%%YYYY%
echo My desired Variable Date to use is : %MyDateVar%
pause
mkdir "E:\Meru\Work\Trace Reports\%MyDateVar%"
pause
Because several hours have now elapsed:
mkdir "E:\Meru\Work\Trace Reports\%date:~0,2%%date:~3,2%%date:~6,4%"
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.
)
)
)
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.
I use the notability app on the iphone & ipad to save class notes but it saves them with awkward file names such as:
"Title Sep 29, 2014 - 2nd Description blah blah.pdf"
"Title Oct 1, 2014 - 2nd Description blah blah.pdf"
This makes it difficult to sort the files in windows file explorer by date as it sorts it alphabetically and the month is the first thing it sorts due to the file name.
I would like to change the file name structure to:
"YYYY-MM-DD - Title - Description blah blah.pdf"
I assume I would need a for loop to use the ren command but the difficulty I'm having is reading the filename and changing the string structure. The title and 2nd description will vary and be composed of more than one word so it cannot be a hard coded string which makes this even trickier. Anybody have any suggestions? Thanks.
"Too tough for batch"? I see the comedians are loose again...
Now it would have been good to have some real examples, but this should work.
#ECHO Off
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
FOR %%a IN ("%sourcedir%\*.pdf") DO (
SET "oname=%%a"
FOR /f "tokens=1,2*delims=,-" %%c IN ("%%~nxa") DO (
SET "oldendname=%%e"
CALL :formdate %%d %%c
)
)
GOTO :EOF
:: parameters are yyyy unknown* Mon dd
:formdate
SET /a yyyy=%1 2>NUL
IF %ERRORLEVEL% neq 0 GOTO :EOF
SET "newtitle="
:formloop
SHIFT
IF "%~3" neq "" SET "newtitle=%newtitle% %~1"&GOTO formloop
SET "mm="
FOR %%z IN (
"Jan=01" "Feb=02" "Mar=03" "Apr=04" "May=05" "Jun=06"
"Jul=07" "Aug=08" "Sep=09" "Oct=10" "Nov=11" "Dec=12"
) DO FOR /f "tokens=1,2delims==" %%m IN (%%z) DO IF "%%m"=="%1" SET "mm=%%n"
IF NOT DEFINED mm GOTO :EOF
SET /a dd=100+%2
ECHO(REN "%oname%" "%yyyy%-%mm%-%dd:~-2%%newtitle% -%oldendname%"
GOTO :eof
You would need to change the setting of sourcedir to suit your circumstances.
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(REN to REN to actually rename the files.
[Edit : fixed to include extension]
New solution using JREN.BAT version 2
For those that like regular expressions, this is very simple using JREN.BAT version 2 - a hybrid JScript/batch command line utility that renames files or folders by applying a regular expression search and replace to the name. JREN.BAT is pure script that runs natively on any Windows machine from XP onward.
This simple one line liner will rename files in the current directory:
jren "^(.* )([A-Z][a-z]{2} \d\d?, \d{4}) -" "ts({dt:$2,fmt:'{iso-dt}'})+' - '+$1+'-'" /j /fm *.pdf
Add the /P rootPath option to rename files in a different directory.
Add the /S option to recursively rename files in all the sub-directories
If you are worried about false date matches, you could make the regex more precise:
jren "^(.* )((?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d\d?, \d{4}) -" "ts({dt:$2,fmt:'{iso-dt}'})+' - '+$1+'-'" /j /fm *.pdf
Here is the original solution using version 1
Here are two alternative solutions using JREN.BAT:
#echo off
setlocal
set "src=."
if "%~1" neq "" set "src=%~1"
:: ($1-) ($2-) ($3-) ($4-) ($5-) ($6-) ($7-) ($8-) ($9-) ($10) ($11) ($12) ($13) ($14--) ($15--)($16------------)
set "find=^(.+?) (?:(Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec)) (\d\d?), (\d{4})((?: - .+)?\.pdf)$"
set "repl=for (i=1; i<=12; i++) if (eval('$'+(i+1))) rtn=$15+'-'+lpad(i,'00')+'-'+lpad($14,'00')+' - '+$1+$16; rtn;"
call jren "%find%" "%repl%" /j /i /p "%src%"
or
#echo off
setlocal
set "src=."
if "%~1" neq "" set "src=%~1"
:: ($1-) ($2--------------------------------------------------------------)($3-------------)
set "find=^(.+?) ((?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d\d?, \d{4})((?: - .+)?\.pdf)$"
set "repl=dt=new Date($2); dt.getFullYear()+'-'+lpad(dt.getMonth()+1,'00')+'-'+lpad(dt.getDate(),'00')+' - '+$1+$3;"
call jren "%find%" "%repl%" /j /i /p "%src%"
Name either of the above as renameNotes.bat, and then use renameNotes without arguments to rename files in the current directory, or renameNotes somePath to rename files in a particular folder. The script can safely be run multiple times - it will only rename files that require it.
As it stands now, the above solutions require a fair amount of user supplied JScript code. I think I may add a built-in date formatter to JREN.BAT in the near future that would make this even simpler.
This question already has an answer here:
Copying files based on date modified in batch file
(1 answer)
Closed 9 years ago.
Thanks for visiting. My question: I receive daily files that are stored as .csv's, typically with the following format: DEVICE_DEVICENumber_DateID. I'd like to move these files into their respective monthly folders (ie 201401) based on the Date portion of the DateID. The DateID is written as the date first followed by a unique device ID (ex YYYYMMDDUNIQUEID - 2014010110).
If I create folders like the one mentioned above (i.e. 201401, 201402, 201403, etc.), is there a simple way to pull a portion of the string to match the folder that I want to direct the file to?
Thanks for your help!
Calbruin
Typical filename:
GO.YO_WTR_SOO5_PT_20140102110.csv
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=.\csvfiles"
SET "destdir=c:\destdir"
FOR /f "delims=" %%a IN ('dir /b /a-d "%sourcedir%\*.csv" ') DO (
SET "csvname=%%~na"
IF NOT "!csvname:*_=!"=="!csvname!" (
CALL :finddate
ECHO MD "%destdir%\!csvname!"
ECHO MOVE "%sourcedir%\%%a" "%destdir%\!csvname!\"
)
)
GOTO :EOF
:finddate
IF /i "%csvname:~-6%"=="_audit" SET "csvname=%csvname:~0,-6%"
IF "%csvname:*_=%"=="%csvname%" SET "csvname=%csvname:~0,6%"&GOTO :EOF
SET "csvname=%csvname:*_=%"
GOTO finddate
When applied to a directory '.\csvfiles` with content
GO.YO-WTR-SOO5-PT-20140102110.csv
GO.YO_WTR_SOO5_PT_20140102110.csv
Produced output
MD "c:\destdir\201401"
MOVE ".\csvfiles\GO.YO_WTR_SOO5_PT_20140102110.csv" "c:\destdir\201401\"
The required commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO MD to MD to actually create the directories. Append 2>nul to suppress error messages (eg. when the directory already exists)
Change ECHO MOVE to MOVE to actually move the files. Append >nul to suppress report messages (eg. 1 file moved)
Amendment - adjustment for ..._audit.csv.