Windows batch rename by date created - windows

There might be a better approach, but my file names are in this format:
name_Sat Apr 11 031806 2015.mp3 (with the spaces)
In order to merge them I need to put them in order, ie. 001, 002, 003. etc.
I currently use this code to move them to a folder on the end of the each day:
#echo off
for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x
:: variables
set SRCFOLDER=C:\srcfolder
set DESTFOLDER=C:\destfolder
set today=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%
set backupcmd= /MOV
robocopy "%SRCFOLDER%" "%DESTFOLDER%\%today%" %backupcmd%
That produces a new folder named YYYY-MM-DD and the files are put there. I will merge them with another program, but I need to have them in a sequence by the time they were created (the time in the filename).
So the question is - How do I do that?
Thanks

If I understand correctly, files are moved to a folder based on the date when the script ran ... and not what date appears in the file name. However, you state that the files in that folder are all created on the same day and already sorted. Try adding this (untested) to your current script:
setlocal EnableDelayedExpansion
set /A Counter=0
REM Since you need folders numbered as 001, we need some padding
set /A PaddingNumber=1000
for /f "delims=" %%A in ('dir /b /a-d "%DESTFOLDER%\%today%\*"') do (
set /A Counter=!Counter!+1
set /A SequenceNumber=%PaddingNumber%+!Counter!
set FileSuffix=!SequenceNumber:~1!
ren "%%~fA" "%%~nA-!FileSuffix!%%~xA"
)
You can choose whether to have the FileSuffix at the start or end.

Related

Batch - Get Today's Date and Use It in the Name of a Directory I Need to Search

I have the following, which compares the contents of two directories and keeps a list of where a folder in one does not exist in the other:
setLocal EnableDelayedExpansion
set "DMZFolder=%WD_DIR%"
set "AMSFolder=D:\Apps\AMS\Files\Orig\UOB\BACKUP"
set count=0
for /f "delims=" %%F in ('dir/b/a-d "%DMZFolder%"') do (
if not exist "%AMSFolder%\%%F" (
set /A count+=1
REM keep file name and put in email later
set list[!count!]=%%F
)
)
Now, rather than search the DMZFolder, I want to get today's date, format it, and add it to DMZFolder to create a new directory to search. So, if the original directory is
C:\DMZFolder\directory
the new directory might be
C:\DMZFolder\directory\2019-12-05
I do this to get today's date:
SET Today=%Date:~10,4%-%Date:~4,2%-%Date:~7,2%
So far, so good. How do I add the string that Today now contains to what is in my DMZFolder variable?
I would rather use wmic:
#echo off
for /f "usebackq tokens=1,2 delims=,=- " %%a in (`wmic os get LocalDateTime /value`) do #if %%i==LocalDateTime (
set string=%%b
)
set Today=%token10:~0,4%-%token10:~4,2%-%token10:~6,2%
set "DMZFolder=%WD_DIR%\%Today%"
Locale differs on devices, so using wmic will be the same across all windows devices.
I figured it out: set "DMZFolder=%WD_DIR%\%Today%"

Adding a textfile with a name to each directory

I'm having some trouble with trying to add a text file to each directory in this directory having a certain name. I have a directory called Daily Notes where I save my notes for the day and I have this further organized by week. So I have a bunch of directories in here such as 6.5.17-6.10.17 and in each of these I need a text file with the name format such as 6.7.17DailyNotes.txt. I know I can easily do this by hand each day, but I have some free time and am trying to learn how to program with cmd. I tried to just make a test text file with a for loop but it saved it to the directory containing the batch file. Here is my code right now:
#echo off
setlocal disabledelayedexpansion
set "folder=%~1"
if not defined folder set "folder=%cd%"
for /D %%a in ("%folder%\*") do (
echo test > test.txt
)
endlocal
So, I want to go into each directory and make 5 text files, one for each day with the format month.day.yearDailyNotes.txt. I was thinking I could just make a variable from reading the directory name and count up in days from that for the text files. Any advice?
Your comment
I know it would be very difficult to handle month changes in the
middle of the week, I was thinking it will be acceptable to just
handle that part manually, so have a file named something like
10.32.17DailyNotes.txt which I manually will change after
makes it much easier (Date/Time Math in Batch is possible, but ugly and involves a lot of code)
#echo off
setlocal enabledelayedexpansion
REM next two lines for simulating your environment:
set "folder=%~dp0"
md 6.5.17-6.10.17 6.11.17-6.16.17 2>nul
REM for every folder
for /d %%f in ("%folder%*.*.*-*.*.*") do (
REM extract day, month and year [from first part of foldername]
for /f "tokens=1-3 delims=.-" %%a in ("%%~nxf")do (
REM calculate "end day" [may be greater than days in that month]
set /a end=%%b+5
REM for [start] to [end]
for /l %%i in (%%b,1,!end!) do (
REM create blank file
break > "%%f\%%a.%%i.%%cDailyNotes.txt"
)
)
)
Iterate over all of the subdirectories and create a test.txt file.
set "folder=%~1"
if not defined folder set "folder=%cd%"
FOR /F "usebackq tokens=*" %%a IN (`DIR /S /B /A:D "%folder%\*"`) DO (
ECHO test > "%%~a\test.txt"
)
#echo off
setlocal disabledelayedexpansion
set "folder=%~1"
if not defined folder set "folder=%cd%"
for /D %%q in ("%folder%\*") do (
echo test "%%q\%%~nxqDailyNotes.txt"
)
ENDLOCAL
Interesting exercise with a couple of twists.
my posted code will simply show 'test "fullfilename" '. Naturally, you could use copy nul "*fullfilename*"' to create an empty file (with>nulto suppress the creation-report) orecho.>"fullfilename"` to create a file containing just an empty line - or whatever.
The main magic is with the gymnastics in creating the filename. Since you are using for/d, the directoryname will appear in %%q. so the required filename is the name+extension part of that directoryname (you and I know it's actually not a filename but the outermost leafname of a directory tree - just don't tell cmd) so we use %%~nxq meaning the name and extension part of the "filename" in %%q (see for /?|more from the prompt for documentation). We then just tack the remainder of the required name on as a literal.
So - why the change to %%q?
Suppose we leave it as %%a. The filename would then be "%%~nxaDailyNotes.txt" and be interpreted as name,extension,attribute,drive of %%a since i is neither a modifier nor a participating metavariable. Changing the metavariable from %%a to %%q removes the misinterpretation.

.bat - Create a menu from folder file list

I don't usually create .bat file, but I made this little script useful for develop.
I'm using this for reading and creating a list of files contained into a folder:
for /f "delims=|" %%f in ('dir /b C:\src\release\android\') do echo %%f
and I found this about how to create a menu starting from a list of file -> Multiple choices menu on batch file?
Now my question is:
I'd like to create a menu with a list of files contained into that folder which I can select (not multiple selection) by pressing it's relative number on the list, but i don't really know how to merge the two bit of code above.
The final result should work something like:
[1] ..
[2] ..
[3] ..
[4] ..
select file:
and it will install the selected file from the folder.
Any suggestion would be really appreciated.
Thanks in advance
This should work unless you're using a version of Windows that doesn't have choice, like if you're still on XP for some reason.
#echo off
setlocal enabledelayedexpansion
set count=0
set "choice_options="
for /F "delims=" %%A in ('dir /a:-d /b C:\src\release\android\') do (
REM Increment %count% here so that it doesn't get incremented later
set /a count+=1
REM Add the file name to the options array
set "options[!count!]=%%A"
REM Add the new option to the list of existing options
set choice_options=!choice_options!!count!
)
for /L %%A in (1,1,!count!) do echo [%%A]. !options[%%A]!
choice /c:!choice_options! /n /m "Enter a file to load: "
:: CHOICE selections get set to the system variable %errorlevel%
:: The whole thing is wrapped in quotes to handle file names with spaces in them
:: I'm using type because I'm not familiar with adb, but you be able to get the idea
type "C:\src\release\android\!options[%errorlevel%]!"
Improving upon SomethingDark's script to run Python scripts in a user's Document folder (I know, not best practice here for brevity's sake), as it currently wouldn't work when there are more than 10 choices:
#echo off
setlocal enabledelayedexpansion
set count=0
set "choice_options="
for /F "delims=" %%A in ('dir /a:-d /b C:\Users\JohnSmith\Documents\*.py') do (
REM Increment %count% here so that it doesn't get incremented later
set /a count+=1
REM Add the file name to the options array
set "options[!count!]=%%A"
)
for /L %%A in (1,1,!count!) do echo [%%A]. !options[%%A]!
::prompts user input
set /p filechoice="Enter a file to load: "
:: Location of python.exe and location of python script explicitly stated
echo Running !options[%filechoice%]!...
"C:\Users\JohnSmith\AppData\Local\Microsoft\WindowsApps\python.exe" "C:\Users\JohnSmith\Documents\!options[%filechoice%]!"

Append folder name to file name and move file using DOS batch

There is folder structure like this:
rootfolder\subfolder1\file1.txt
rootfolder\subfolder1\fileA.txt
rootfolder\subfolderX\file2.txt
rootfolder\subfolderX\fileC.txt
Need to append the foldername to the filename and include current datetime. Then move the renamed file to the rootfolder i.e. like below:
rootfolder\subfolder1_file1_<datetime>.txt
rootfolder\subfolder1_fileA_<datetime>.txt
rootfolder\subfolderX_file2_<datetime>.txt
rootfolder\subfolderX_fileC_<datetime>.txt
Does anyone know script that can do this? Thanks a lot!
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "datetime=%date:/=-%%time::=.%"
PUSHD "%sourcedir%"
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%\*"'
) DO (
FOR /f "delims=" %%d IN ('dir /b/a-d ".\%%a\*.txt" 2^>nul') DO (
ECHO(move "%sourcedir%\%%a\%%d" "%sourcedir%\%%a_%%~nd_%datetime%%%~xd"
)
)
popd
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
I've chosen to simply filter for .txt files - adjust the filemask to suit.
I don't know your date format or the date format you expect. You've not said whether you want the current date/time or the file's date/time to be inserted. current assumed.
The required MOVE commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(MOVE to MOVE to actually move the files. Append >nul to suppress report messages (eg. 1 file moved)

How to find files older than X time in a directory

Have a need to find files in a folder that are older than X hours. Have to do this in batch because this is an older server that we don't want to load anything else on. This is based on Find out if file is older than 4 hours in Batch file, but that solution was written for only for one static filename. I have adjusted it for multiple files, and US date format, but the problem I am having in the file minutes it is picking up the 'a' or 'p' for am or pm. I have posted my partial solution below (does not perform date math and echos to screen filename and date/time values). Any ideas on how to get rid of a or p?
rem extract current date
for /f "tokens=1-5 delims=.,/ " %%a in ("%date%") do (
set day=%%c&set mon=%%b&set yr=%%d
)
REM Extract Current Time
for /f "tokens=1-5 delims=.:, " %%a in ("%time%") do (
set hr=%%a&set min=%%b
)
REM BUILD LIST OF FILES IN DIRECTORY
dir /B /O:N c:\mydir\*myfilestub*.* >list.txt
Rem LOOP THROUGH LIST OF FILES and CALL SUBROUTINE TO CHECK FILE DATE
For /F %%A in (list.txt) DO (CALL :CHECKFILE %%A)
GOTO :EOF
:CHECKFILE
REM CHECKING FILE %*
set filename=%*
rem extract file date and time
for /f "tokens=1-5 delims=.:,/ " %%a in ('"dir c:\mydir\%filename%|find "%filename%""') do (
set fday=%%a&set fmon=%%b&set fyr=%%c&set fhr=%%d&set fmin=%%e
)
ECHO %FILENAME% %fday% %fmon% %fyr% %fhr% %fmin%
GOTO :EOF
Thanks to http://www.dostips.com/DtTipsStringManipulation.php, I got the answer I was needing, just added a line below the for loop that was getting the file date
SET fmin=%fmin:~0,2%
It is nothing short of amazing what you can still accomplish with just DOS on a windows server. I know this script could be cleaned up and shortened I am sure, but it suits my purposes.

Resources