I used this script to rename files in bulk with a unique time stamp in a batch file. The idea is to use the second and millisecond to create a unique number, which is added to the filename. The why? The filenames being used is so similar in the naming convention that it is triggering errors on the import program into the database. What doesn't trigger the error is the uniqueness of the filename, which is why I thought of a second and millisecond stamp to the prefix. Now, the code works as intended, but the stamp is not unique. It is as if the code pulls the value from the system and applies to all of the files in the folder instead of one file at a time.
Assume my file names are like this:
File1.txt
File2.txt
File3.txt
File4.txt
When the script is run, it renames the files like this:
1410File1.txt
1410File2.txt
1410File3.txt
1410File4.txt
I was hoping the script would do it like this:
1410File1.txt
1411File2.txt
1412File3.txt
1413File4.txt
The code I used to help me with this problem:
#echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
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 Mil=%dt:~14,6%
set stamp=%Sec%%Mil%
CHDIR /D "c:\TEST\FILES\"
for %%a in (*.*) do ren "%%a" "%stamp%%%a"
Is there an additional programming code that is needed to ensure each filename is renamed differently? I'm on Windows 10 using a simple .bat file. On any given day, I would end up renaming anywhere from 600 up to 1000 files in one sitting so any help would be greatly appreciated!
Thanks in advance!
You answered your own question:
Now, the code works as intended, but the stamp is not unique. It is as if the code pulls the value from the system and applies to all of the files in the folder instead of one file at a time.
Take a look at your code. You
Compute the timestamp once at the start of the run:
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
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 Mil=%dt:~14,6%
set stamp=%Sec%%Mil%
cd down to the desired directory:
CHDIR /D "c:\TEST\FILES\"
iterate over the files in the directory, adding the same timestamp to each file:
for %%a in (*.*) do ren "%%a" "%stamp%%%a"
You need to recompute the timestamp on every iteration of the final loop.
I would also add a pause of a few milliseconds in the loop to ensure that at least 1 millisecond has elapsed between computations of the timestamp.
Related
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\
I have to seperate codes.
This creates a directory with only the date, but i don't know how to put the time on the end.
for /f "tokens=1* delims=" %%a in ('date /T') do set datestr=%%a
mkdir c:\%date:/=%
And I have this to copy the files:
robocopy "%appdata%\saves" "C:\Users\redfi\OneDrive\Savesbackup" /e /xf
They both work individually, but I want to put them in one batch.
I want it to create the directory with the current date and time, and then copy the saves in it. So I can restore older saves if I want.
Thank you!
I managed to figure it out. You might need to edit the date formats.
echo off
set CUR_YYYY=%date:~0,4%
set CUR_MM=%date:~5,2%
set CUR_DD=%date:~8,2%
set CUR_HH=%time:~0,2%
if %CUR_HH% lss 10 (set CUR_HH=0%time:~1,1%)
set CUR_NN=%time:~3,2%
set CUR_SS=%time:~6,2%
set CUR_MS=%time:~9,2%
set SUBFILENAME=%CUR_YYYY%.%CUR_MM%.%CUR_DD%_%CUR_HH%.%CUR_NN%
mkdir C:\Users\redfi\OneDrive\Minecraftbackup\%SUBFILENAME%
robocopy "%appdata%\.minecraft\saves" "C:\Users\redfi\OneDrive\Minecraftbackup\%SUBFILENAME%" /e /xf
My Problem
As there are a ton of threads that address 'using a batch file to return file modify date' (or delete files older than, etc) - let me first specify my issue.
I'm looking to create a batch (not PowerShell, etc) that will return the last modify date of a specific file given UNC path and filename.
Code, Attempt 1
I've taken a peek at a few potential solutions on other threads, but I've run into a number of unique issues. The first and most obvious solution for this would be the "ForFiles" command in batch. For example:
set myPath=\\myUNCpath
set myFile=myFileName.csv
forfiles /p "%myPath%" /m %myFile% /c "GoTo OldFile" /d -6
Thus, if the file is older than I want -- jump to a specific section of my batch for that. However, this yields the error:
ERROR: UNC paths (\machine\share) are not supported.
However, this cmd won't work due to the use of UNC (which is critical as this batch is called by system's task scheduler). So it seems like the 'ForFiles' cmd is out.
Code, Attempt 2
I could go a more round about way of doing it, but simply retrieving the last modified date of the file (which in batch would return a string). I can truncate the string to the necessary date values, convert to a date, and then compare to current date. To do that, I've also looked into just using a for loop such as:
set myFile=\\myUNCpath\myFileName.csv
echo %myFile%
pause
FOR %%f IN (%myFile%) DO SET myFileDate=%%~tf
echo %myFileDate%
pause
Though my first debug echo provides the proper full file name, my second debug just returns ECHO is off., which tells me it's either not finding the file or the for loop isn't returning the file date. Not sure why.
I've also tried minor changes to this just to double check environmental variable syntax:
FOR %%f IN (%myFile%) DO SET myFileDate=%%~ta
Returns %ta
And finally:
FOR %%f IN (%myFile%) DO SET myFileDate=%~ta
Which without the extra '%', just crashes the batch.
I'm really at a loss at this point. So any tips or guidance would be greatly appreciated!
Using forfiles to a UNC path can be used using PushD
For just echoing the file older than x in UNC path, simply just use
PushD %myPath% &&(
forfiles -s -m %myFile% -d -6 -c "cmd /c echo /q #file
) & PopD
Here is one way how to use goto if file older than x found in UNC path using your examples.
if not exist "C:\temp" mkdir C:\temp
if not exist "C:\temp\test.txt" echo.>"c:\temp\test.txt"
break>"c:\temp\test.txt"
set myPath=\\myUNCpath
set myFile=myFileName.csv
PushD %myPath% &&(
forfiles -s -m %myFile% -d -6 -c "cmd /c echo /q #file >> c:\temp\test.txt"
) & PopD
for /f %%i in ("C:\temp\test.txt") do set size=%%~zi
if %size% gtr 0 goto next
:next
Huge thanks to both #Squashman and #MadsTheMan for the help. Luckily this batch finally is the piece of code that I can take to my boss to push switching over to at least using PowerShell!
Anyway, for those of you looking for the best way to get a UNC path file's modify date, here is what I've come up with. Not very different than other threads (and a thanks goes out to Squashman for spotting my missing " " in the for loop).
set myFile=\\myUNCpath\myFileName.ext
FOR %%f IN ("%myFile%") DO SET myFileDate=%%~tf
::And if you'd like to try to do long winded calculations you can further break the dates down via...
set fileMonth=%myFileDate:~0,2%
set fileDay=%myFileDate:~3,2%
set fileYear=%myFileDate:~6,4%
set currentDate=%date%
set currentMonth=%currentDate:~4,2%
set currentDay=%currentDate:~7,2%
set currentYear=%currentDate:~10,4%
The plan was to then convert the strings to integers, and then use a switch-case block to determine if the variance between dates was acceptable... blah blah blah.
Long story short - if you are limited to batch (and not creating secondary files -- such as a csv or the temp file suggested by MadsTheMan) you're going to have a really long script on your hands that still might have flaws (like leap year, etc unless you're adding even MORE code), when you could just make the comparison calculation using one line of code in other programs.
I have a daily process which generates some zip files out of files that are being created by other processes. I need to create a daily log file which indicates the timestamps the contents of one specific file of each zip file that is found.
I created the following batch script which seemed to work yesterday on my test system, but not anymore today, no idea why...
set VersionDirectory=C:\Test\VersionX\
set ResultOutputFile=C:\Test\LogFile.txt
for /f %%f in ('dir /b %VersionDirectory%\Installable\Packages\pattern*.zip') do (
mkdir %temp%\%%f\
unzip -extract -dir %VersionDirectory%\Installable\Packages\%%f %temp%\%%f\ > nul
for %%a in (%temp%\%%f\InstallScript.xml) do set InstallScriptXMLDate=%%~ta
rmdir /s /q %temp%\%%f\
echo %%f [package from %InstallScriptXMLDate%] >> %ResultOutputFile%
)
Short summary of what this file is supposed to do:
Loop through each pattern*.zip file in C:\Test\VersionX\ directory
unzip this file to the %temp%\%%f directory (where %%f is the filename)
Get the timestamp of the %temp%\%%f\InstallScript.xml and put it in the %InstallScriptXMLDate% variable
Delete the %temp%\%%f directory
Echo the filename (%%f) and timestamp (%InstallScriptXMLDate%) into the log file
As of now the log file just contains the filenames, followed by the string '[package from ]' string, but missing the actual date timestamp
The unzipping and removing of the zip files is working flawlessly, it's just the timestamp that's not being set.
You are setting a variable and using it in the same block. This cannot work in cmd because environment variables are expanded when a statement is parsed not when it's executed. So when the loop is run all variables have already been replaced with the values they had before the loop.
Put
setlocal enabledelayedexpansion
at the start of your batch and use !InstallScriptXmlDate! instead of %InstallScriptXmlDate%.
Another note: for is perfectly capable of iterating over files by itself, you almost never need to iterate over dir /b output with for /f. In fact, it can introduce problems that can be avoided with
for %%f in (%VersionDirectory%\Installable\Packages\pattern*.zip)
how get the date and time of the last modified particular TYPE file in that directory
let me explain with an example
if i use the command dir *.reo /o:d
i get the all *.reo files in that directory sorted according to the date ..
this is the the last line of the output
29-03-2010 11.31 arun.reo
now i just want to copy the date and time of the last created file in variable or file .is it possible ?
You can do this using a batch file like this:
#echo off
setlocal enableextensions
for /f "delims=" %%f in ('dir *.reo /o:-d /b') do (
set dt=%%~tf
goto endloop
)
: endloop
echo %dt%
A little explanation:
dir *.reo /o:-d /b produces a list of all .reo files in the current directory, sorted by date in descending order (so that the last modified file comes first).
%%~tf expands to the date of the file specified by the %f variable.
It depends on what os your using. If you want just the last file
command one pipes the complete directory into a temp file
dir *.reo /o:d > temp.txt;
command two gets the last line of the temp file. Only works if you have the windowserver 2003 install which the link is provided below.
tail - 1 temp.txt;
Go to the Microsoft Windows Server 2003 download section at http://www.microsoft.com/windowsserver2003/
downloads/tools/default.mspx. Or, if that link does not work, visit http://www.microsoft.com/ and search for "Windows 2003". Once there, choose the "Downloads -> Tools" link.