Copying files into new folders named based on file dates

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Tim86
Posts: 4
Joined: 23 Mar 2013 22:37

Copying files into new folders named based on file dates

#1 Post by Tim86 » 23 Mar 2013 22:52

I need help. I am very weak at DOS, and would like to create a .bat file that does the following.

Assign a source folder variable and a target folder variable.
Find all files in the source folder which match a filename pattern of *.jpg. Look recursively in all subfolders, as well.
Determine the modified date of each file.
Set a year variable from the modified date, YYYY.
Set a month variable from the modified date, MM.
Copy each file into the appropriate folder %target%\YYYY\MM\
Don't change the filename.
If the target folder doesn't already exist, create it before the copy.

This should be a simple task, I think. But like I said, I'm pretty weak at this skill. Can any of you impress me? I don't need this to be super-fast, because I'm only copying about 100 files on average each time I run the script.

By the way, my computer is Windows 8 64-bit, if it matters. And my date format is "Sat 03/23/2013" when I run echo %date%.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Copying files into new folders named based on file dates

#2 Post by foxidrive » 23 Mar 2013 23:04

It sounds like an academic task...

How about you start it and do what you can, first. Post that here and you can get some help with your questions.
It will involve using a for-in-do loop.

Here's another clue:

Code: Select all

@echo off
for %%a in (*.jpg) do echo %%~ta

Tim86
Posts: 4
Joined: 23 Mar 2013 22:37

Re: Copying files into new folders named based on file dates

#3 Post by Tim86 » 23 Mar 2013 23:28

Here is my lousy attempt. I know there are all kinds of problems here, including the fact that I don't think it searches recursively.

Code: Select all

@echo off
cls
set src=C:\Working\Source
set target=C:\Working\Target\Pictures
cd %src%
For %%a in (*.jpg) Do (
   set filedate=%%~ta
set yyyy=%filedate:~11,4%
set mm=%filedate:~5,2%

mkdir %target%\%yyyy% > nul: 2> &1
mkdir %target%\%yyyy%\%mm% > nul: 2> &1

set dest=%target%\%yyyy%\%mm%

echo copying %1 to %dest%\.
copy %1 %dest%\. > > C:\Working\copyimages.log

)

pause

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Copying files into new folders named based on file dates

#4 Post by foxidrive » 23 Mar 2013 23:38

This is untested: it uses delayed expansion to set the variables within the loop.

Code: Select all

@echo off
setlocal enabledelayedexpansion
set "src=C:\Working\Source"
set "target=C:\Working\Target\Pictures"
For /f "delims=" %%a in ('dir "%src%\*.jpg" /b /s /a-d ') Do (
set filedate=%%~ta
set yyyy=!filedate:~11,4!
set mm=!filedate:~5,2!
set d=!yyyy!!mm!
mkdir "%target%\!d!" 2>nul
echo copying "%%a" to "%target%\!d!"
copy /b "%%a" "%target%\!d!" >nul
)

pause

Tim86
Posts: 4
Joined: 23 Mar 2013 22:37

Re: Copying files into new folders named based on file dates

#5 Post by Tim86 » 24 Mar 2013 08:30

That's awesome, it is working! Thank you so much!!! I did some tweaking on the date format, and added another loop for copying my video files to a different target folder.

I'm trying to track each copy in a logfile, as well. But it isn't creating my file. What else do I need to change here?
Also, if I wanted to grab all the *.gif images within the same loop as the *.jpg, is that possible?

Code: Select all

@echo off
setlocal enabledelayedexpansion
set "src=C:\Working\Source"
set "target=C:\Working\Target\Pictures"
set "target2=C:\Working\Target\Videos"
set "logfile=C:\Working\MediaTransferLog.txt"

rem loop for copying images
For /f "delims=" %%a in ('dir "%src%\*.jpg" /b /s /a-d ') Do (
set filedate=%%~ta
rem echo filedate = !filedate!
set yyyy=!filedate:~6,4!
set mm=!filedate:~0,2!
set d=!yyyy!\!mm!
rem echo d = !d!
mkdir "%target%\!d!" 2>nul
echo %date% %time% --- Copied "%%a" to "%target%\!d!" >> %logfile% >nul
copy /b "%%a" "%target%\!d!" >nul
)
rem pause

rem loop for copying videos
For /f "delims=" %%a in ('dir "%src%\*.mov" /b /s /a-d ') Do (
set filedate=%%~ta
rem echo filedate = !filedate!
set yyyy=!filedate:~6,4!
set mm=!filedate:~0,2!
set d=!yyyy!\!mm!
rem echo d = !d!
mkdir "%target2%\!d!" 2>nul
echo %date% %time% --- Copied "%%a" to "%target2%\!d!" >> %logfile% >nul
copy /b "%%a" "%target2%\!d!" >nul
)
pause

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Copying files into new folders named based on file dates

#6 Post by foxidrive » 24 Mar 2013 12:09

You need to use delayed expansion for the date and time, and remove the >nul from the end for the log file.

Code: Select all

echo !date! !time! --- Copied "%%a" to "%target%\!d!" >> "%logfile%"



Add this bit for .gif files.

For /f "delims=" %%a in ('dir "%src%\*.jpg" "%src%\*.gif" /b /s /a-d ') Do (

Tim86
Posts: 4
Joined: 23 Mar 2013 22:37

Re: Copying files into new folders named based on file dates

#7 Post by Tim86 » 30 Mar 2013 15:02

This is just fabulous, foxidrive! I did a little more tweaking to add a prompt at the beginning, confirming if I really wanted to proceed, and also to echo some feedback to the user while it is running. I also changed it to a move operation instead of a copy. Then I changed it to use my SD card as the source on the E: drive, and the targets are the Pictures and Videos libraries. It works great...exactly what I wanted! Thanks so much.

Code: Select all

@echo off
setlocal
:PROMPT
echo.
SET /P AREYOUSURE=Do you want to move all images and videos from the SD card? (Y/[N])?
IF /I "%AREYOUSURE%" NEQ "Y" (
echo.
echo You did not select "Y"...closing the copy program now...
echo.
pause
GOTO END)

setlocal enabledelayedexpansion
set "src=E:"
set "target=C:\Users\Tim\Pictures"
set "target2=C:\Users\Tim\Videos"
set "logfile=C:\Working\Logs\MediaTransferLog.txt"

rem loop for copying images
echo.
echo Moving image files now...
rem Add this bit of code for .gif files.  Similar pattern for any filetype you want to move
rem For /f "delims=" %%a in ('dir "%src%\*.jpg" "%src%\*.gif" /b /s /a-d ') Do (
For /f "delims=" %%a in ('dir "%src%\*.jpg" /b /s /a-d ') Do (
set filedate=%%~ta
rem echo filedate = !filedate!
set yyyy=!filedate:~6,4!
set mm=!filedate:~0,2!
set d=!yyyy!\!mm!
rem echo d = !d!
mkdir "%target%\!d!" 2>nul
rem copy /b "%%a" "%target%\!d!" >nul
move /Y "%%a" "%target%\!d!" >nul
echo !date! !time! --- Moved "%%a" to "%target%\!d!" >> "%logfile%"
)
echo.
echo Images have been moved to "%target%"
rem pause

rem loop for copying videos
echo.
echo Moving video files now...
For /f "delims=" %%a in ('dir "%src%\*.mov" /b /s /a-d ') Do (
set filedate=%%~ta
rem echo filedate = !filedate!
set yyyy=!filedate:~6,4!
set mm=!filedate:~0,2!
set d=!yyyy!\!mm!
rem echo d = !d!
mkdir "%target2%\!d!" 2>nul
rem copy /b "%%a" "%target2%\!d!" >nul
move /Y "%%a" "%target2%\!d!" >nul
echo !date! !time! --- Moved "%%a" to "%target%\!d!" >> "%logfile%"
)
echo.
echo Videos have been moved to "%target2%"
echo.
echo All file moves have been logged in "%logfile%"
echo.
pause
:END
endlocal

Samir
Posts: 384
Joined: 16 Jul 2013 12:00
Location: HSV
Contact:

Re: Copying files into new folders named based on file dates

#8 Post by Samir » 16 Mar 2014 09:01

foxidrive wrote:This is untested: it uses delayed expansion to set the variables within the loop.

Code: Select all

@echo off
setlocal enabledelayedexpansion
set "src=C:\Working\Source"
set "target=C:\Working\Target\Pictures"
For /f "delims=" %%a in ('dir "%src%\*.jpg" /b /s /a-d ') Do (
set filedate=%%~ta
set yyyy=!filedate:~11,4!
set mm=!filedate:~5,2!
set d=!yyyy!!mm!
mkdir "%target%\!d!" 2>nul
echo copying "%%a" to "%target%\!d!"
copy /b "%%a" "%target%\!d!" >nul
)

pause
Lovely code! I had to adjust the YYYY and MM start and stop parameters (6,4 and 0,2 for anyone that's needing them), and was able to save HOURS of manually sorting files. Thank you!

Post Reply