Search code examples
batch-filexcopy

How to copy several folders to new directory with current year and month in directory name?


I have two folders called Roads and Kerbs. I want to copy both folders (keeping the folder name) into a backup folder with the current year/month as the folder name.

Example: The backup folder name will be 201812 and if I open it the two folders Roads and Kerbs will be under it. I want to create a batch file with xcopy to do this function for me.

The current code only opens a folder named 01 and only copies the folder content. I want the month/year and then the two folders under it with their content.

@echo off
set curr_date=%DATE:~10,2%-%DATE:~7,2%
mkdir "C:\Roads_backup\%curr_date%"
xcopy "C:\Roads" "C:\Roads_backup\%curr_date%" /D/S/H/V/C/F/K

How to copy the two folders to new directory with current year and month in directory name?


Solution

  • CMD is Horrible at Dates

    For anything of any complexity whatsoever, I'd avoid using %DATE% and %TIME% in favor of not reinventing the wheel. PowerShell comes standard (though with different versions) on every Windows platform released in the past 10 years, and uses a reasonably full-featured date/time library.

    FOR /F "usebackq" %%d IN (`PowerShell -NoProfile -ExecutionPolicy Bypass -Command "Get-Date -UFormat '%%Y%%m'" ^<NUL`) DO SET "STAMP=%%~d"
    

    This will set the envvar STAMP to the formatted date string, controlled by the -UFormat parameter. It won't matter what the computer's locale or language is, and it'll work on anything with PowerShell (standard on Win7 and beyond).

    It is a little wordy, but you can also easily copy/paste it without having to recalculate all the string offsets needed to carve up the values in %DATE% and %TIME% every time you want format the current date.

    You can also do the same thing with dates other than the current one, as well as subtract timespans from the current date to get things like "a week ago"—something excruciatingly painful to do with pure batch/CMD alone.

    Copying Directories

    You'll probably want to use the /I (target name is a dir) parameter of xcopy as well as specify the target directory name to use (otherwise, xcopy will put the contents of Roads into the target directory without creating a directory named Roads).

    xcopy "C:\Roads" "C:\Roads_backup\%STAMP%\Roads" /I/D/S/H/V/C/F/K
    

    I'm not sure if you need /D if you're always going to be creating new dirs, since that means "only copy newer files."