I figured out a while ago that I wanted to store my photos organized by time stamp. So there is a folder for each year and inside that there are folders named in the format of "YYYY-MM-DD". The complication is that all the folders on those discs I mentioned were made before I decided on this convention. Most of them were stored as "MM-DD-YYYY". Now the main reason I like "YYYY-MM-DD" is because it sorts nicely, that's really about it.
So, How do I name about 4 years worth of windows directories from "MM-DD-YYYY" to "YYYY-MM-DD" quickly? Well, I wrote a batch file to do it. Since I had all the folders I wanted to rename in one directory all I had to do was step through each one that matched the pattern I wanted to change, and issue the command to change them.
The problem is to rename something you need to know the old name, and the new name. So I needed to be able to move the year. month and day part of the name around independently for each one. Well, that's what I learned today.
The batch file I ended up with, which worked for the most part is here and nice and short:
@Echo on & SetLocal EnableExtensions
For /F "tokens=1,2,3* delims=-" %%I IN ('dir /ad /b ??-??-????')
DO rename "%%~I-%%~J-%%~K" "%%~K-%%~I-%%~J"
To break it down, line one:
@Echo on & SetLocal EnableExtensions
Basically turns on "echo" so I can see what it is doing while it's working. The "SetLocal EnableExtensions" inherits the environment from the parent environment and keeps any environment changes I make local to this batch file and probably don't need it for this little run.
The second line is the complicated one:
For /F "tokens=1,2,3* delims=-" %%I IN ('dir /ad /b ??-??-????')
The first thing you see is the "For" loop, which lets me do the same thing over and over on a set of items. The set I want to step through is the Windows folders with the names I want to change. The "/F" turns on file parsing (so we can muck with the names). The "IN ('dir /ad /b ??-??-????')" gives me that, basically saying give me all the directories (by running the "dir" or directory listing command with the "/ad" options which tell it to just list directories/folders) that have the name matching the pattern "??-??-????" (I'm not going to explain pattern matching :-). The "%%I IN"of the "for" loop says when I'm in the loop, the item I'm supposed to be working on now is called (referenced by) the variable called "%%I".
Now the third line is what we do through each iteration of the loop:
DO rename "%%~I-%%~J-%%~K" "%%~K-%%~I-%%~J"
We simply run the Windows "rename" command and the syntax is pretty much current name first, then the new name you want it changed to. Now we just need to explain all the gobbledygook in there. That is where the "tokens" and "delims" file parsing features (that we turned on with the "/F") of the "for" loop come in. They basically help you parse the items of the set as you step through them and this is how those two items break down:
- "delims=" specifies a delimiter set, or what separates the pieces you want. Whatever characters you specify replaces the default delimiter set of space and tab.
- "tokens=" specifies which tokens or pieces from each line are to be passed into the "for" loop body for processing.
Oh, you may have noticed the tilde ("~") in the names. That's a variable modifier that basically means when you use what is in here, expand it, which removes any surrounding quotation marks ("").
So the "%%I" variable holds the MM, "%%J" holds the DD and "%%K" holds the YYYY. So shuffling the order around using the rename command is basically saying here is my original directory name "%%~I-%%~J-%%~K" and here is the new name I want it to have "%%~K-%%~I-%%~J".
So, I put the three lines I started talking about way up at the top into a file called "renam.bat" and put it into the same directory where all the "MM-DD-YYYY" named directories were. Then I ran it by opening a "cmd" window and changing to the directory where all this stuff was sitting. I ended up with all the directories renamed into the "YYYY-MM-DD" format.
The only glitch was that I had some directories named differently. Some didn't have all the digits of the dates, like "MM-DD-YY" or "M-D-YY", and they just didn't get processed. Others were of the format "MM-DD-YY-Something" and those did get processed. Luckily, that's what the asterisk in the "tokens" keyword is for, it tells it to keep anything after piece three as a part of piece three. So a couple of the names got slightly jumbled, but all those special cases were easy enough to fix by hand. I didn't want to spend the time working on them in the script as there were only a few of them.
Of course there is probably several ways this could have been done, and probably some more elegantly. But I learned something new (the "tokens" and "delims" stuff) and it worked, and it was quick because there were a lot of directories that needed to be renamed and now all my photos are copying to the NAS as I type this up. So I'm happy.
To get it to work under Windows XP (Per the comment below) just make the "for" command be one line long. Remove the carriage return before the "DO" and it works. I just tested it on a XP VM.
For /F "tokens=1,2,3* delims=-" %%I IN ('dir /ad /b ??-??-????') DO rename "%%~I-%%~J-%%~K" "%%~K-%%~I-%%~J"
Thanks
I have tried your batch file under windows xp (cmd window) but it is not working (it says 'syntax of the command is incorrect....) - do you have a version for xp?
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDeleteThanks mate, worked a treat. Mine were in DD-MM-YYYY so had to change the I and J around. To get the single date directories (eg D-MM-YYYY), I just changed the search pattern to match (?-??-????).
ReplyDeleteThanks! The missing link in sorting my iPhone photo's in seperate-date-folders-batchfile. The batch file I had gave DD-MM-YYYY. With these extra commands I end up with YYYY_MM_DD. That's better for my OCD ;)
ReplyDeleteThank you Tony for this helpful blog post! I was able to adjust your Batch-File to my needs.
ReplyDelete"rename_folders_from_dd.mm.yyyy_to_yyyy-mm-dd.bat"
@Echo on & SetLocal EnableExtensions
For /F "tokens=1,2,3* delims=." %%I IN ('dir /ad /b ??.??.????') DO rename "%%~I.%%~J.%%~K" "%%~K-%%~J-%%~I"
Hello! I need to convert DD.MM.YYYY to YYYY.MM.DD
ReplyDeleteSo I changed '-' to '.' in your example.
Trying to run this batch on Windows 10 powershell as admin and separately - nothing happens. What am I doing wrong?
@Echo on & SetLocal EnableExtensions
For /F "tokens=1,2,3* delims=." %%I IN ('dir /ad /b ??.??.????') DO rename "%%~I.%%~J.%%~K" "%%~K.%%~I.%%~J"
upd: Solved this exact task via "Bulk rename utility"
DeleteI didn't test this in powershell, I used windows batch (*.bat) files.
ReplyDeleteIn my understanding Powershell is just more advanced ver. of Command prompt (cmd).
ReplyDeleteAnyway... I couldn't figure it out... So I went for "Bulk rename utility" which is great though takes some time learning )
Hello, how do you tell .bat file which folders to rename from dd-mm-yyyy Friday to yyyy-mm-dd Friday ie my folder is Drive D: Folder Sony 2018-DL a rename folder would be great in Windows 10 hint hint … Microsoft.
ReplyDeleteI Open Folder [view] file name Extensions and run as admin....