Jason Atherton
Jason Atherton

Reputation: 3

Batch File to Loop Through Folders and Copy Folder & Contents to Directory with Same Folder Name

Each month, corporate dumps (saves) a varying number of files into a varying number of folders on a shared network drive. The files contain information, in either an .xlsx or .pdf file format, and the folders represent different projects. The folder names consist of the project number only (i.e. 12345, 15241-0001,16755-0004, etc...). Typically a five digit number or five digit number followed by a hyphen and then a four digit number.

I would like to be able to create a batch file that can be ran to loop through the folders that corporate dumps to the shared network share drive and then copies the project folder and contents (files) to a different shared network drive that contains the corresponding project folders used by operations in my department. The project folder names on the operations shared network drive contain the project number, a space, a hyphen, another space, and then the project name (i.e. 12345 - Project 1, 15241-0001 - Project 22, 16755-0004 - Project 12, etc...)

Update... Magoo you have been spot-on and a great help, as I am learning from your posts. I failed to take into account is that the sub-projects on the operations side are all in main-project folders:

u:\destdir\2015\15241\15241-0001 - Project 06 u:\destdir\2015\15241\15241-0001 - Projekt 60 u:\destdir\2016\16755\16755-0004 - Project 14

So the script does not copy the files to the sub-projects as the script believes the destination does not extist. Is it possible to get the first five characters of the project and insert into the destination directory of the xcopy command?

Upvotes: 0

Views: 8142

Answers (1)

Magoo
Magoo

Reputation: 80193

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
FOR /f "delims=" %%a IN (
 'dir /b /ad "%sourcedir%\*" '
 ) DO (
 FOR /f "delims=" %%b IN (
  'dir /b /ad "%destdir%\%%a*" '
  ) DO (
  ECHO(XCOPY /s "%sourcedir%\%%a\*" "%destdir%\%%b\"
)
)

GOTO :EOF

You would need to change the setting of sourcedir and destdir to suit your circumstances.

The required XCOPY commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(XCOPY to XCOPY to actually copy the files.


Edit : revision in the light of futher half-information.

Assuming the destination structure is ...\2012\12???(-?????) - waffle then

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
FOR /f "delims=" %%a IN (
 'dir /b /ad "%sourcedir%\*" '
 ) DO CALL :process "%%a"

GOTO :EOF

:process
SET "year=%~1"
SET /a year=20%year:~0,2%
SET "copied="
FOR /f "delims=" %%b IN (
 'dir /b /ad "%destdir%\%year%\%~1*" 2^>nul'
 ) DO IF DEFINED copied (ECHO %1 NOT copied to duplicate destination "%destdir%\%year%\%%b\"
 ) ELSE (
  SET "copied=%destdir%\%%b\"
  ECHO(                    XCOPY /s "%sourcedir%\%~1\*" "%destdir%\%year%\%%b\"
 )
)
IF DEFINED copied (ECHO %1 WAS copied to destination "%copied%"
) else (ECHO %1 WAS NOT copied - no destination found)
GOTO :EOF

You would need to change the setting of sourcedir and destdir to suit your circumstances.

Test results:

Destination directory structure

u:\destdir\2012
u:\destdir\2015
u:\destdir\2016
u:\destdir\2012\12345 - Project 98
u:\destdir\2015\15241-0001 - Project 06
u:\destdir\2015\15241-0001 - Projekt 60
u:\destdir\2016\16755-0004 - Project 14

Process output:

                    XCOPY /s "U:\sourcedir\t w o\12345\*" "U:\destdir\2012\12345 - Project 98\"
"12345" WAS copied to destination "U:\destdir\12345 - Project 98\"
                    XCOPY /s "U:\sourcedir\t w o\15241-0001\*" "U:\destdir\2015\15241-0001 - Project 06\"
"15241-0001" NOT copied to duplicate destination "U:\destdir\2015\15241-0001 - Projekt 60\"
"15241-0001" WAS copied to destination "U:\destdir\15241-0001 - Project 06\"
                    XCOPY /s "U:\sourcedir\t w o\16755-0004\*" "U:\destdir\2016\16755-0004 - Project 14\"
"16755-0004" WAS copied to destination "U:\destdir\16755-0004 - Project 14\"
"13234-1234" WAS NOT copied - no destination found

Note that the xcopy lines are indented for ease-of-separation.

Hyphens work for me!


Revision to proess exclude list - on the assumption that the exclude-list will be shorter than the include-list (2 line change - add the exclude-list set and process that list.

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
SET "excluding=16755-0004"
FOR /f "delims=" %%a IN (
 'dir /b /ad "%sourcedir%\*" '
 ) DO CALL :process "%%a"

GOTO :EOF

:process
FOR %%x IN (%excluding% dummy) DO IF "%~1"=="%%x" ECHO %1 WAS NOT copied - excluded&GOTO :EOF 
SET "year=%~1"
SET /a year=20%year:~0,2%
SET "copied="
FOR /f "delims=" %%b IN (
 'dir /b /ad "%destdir%\%year%\%~1*" 2^>nul'
 ) DO IF DEFINED copied (ECHO %1 NOT copied to duplicate destination "%destdir%\%year%\%%b\"
 ) ELSE (
  SET "copied=%destdir%\%%b\"
  ECHO(                    XCOPY /s "%sourcedir%\%~1\*" "%destdir%\%year%\%%b\"
 )
)
IF DEFINED copied (ECHO %1 WAS copied to destination "%copied%"
) else (ECHO %1 WAS NOT copied - no destination found)
GOTO :EOF

Note the inclusion of dummy to ensure that the list in the for %%x loop is not empty.


And for the next requirement ("project" level in directory) One more line - but I commened-out the excluding line for ease-of-testing.

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
REM SET "excluding=16755-0004"
FOR /f "delims=" %%a IN (
 'dir /b /ad "%sourcedir%\*" '
 ) DO CALL :process "%%a"

GOTO :EOF

:process
FOR %%x IN (%excluding% dummy) DO IF "%~1"=="%%x" ECHO %1 WAS NOT copied - excluded&GOTO :EOF 
SET "year=%~1"
SET /a year=20%year:~0,2%
FOR /f "tokens=1,2delims=-" %%x IN (%1) DO IF NOT "%%y"=="" SET "year=%year%\%%x"
SET "copied="
FOR /f "delims=" %%b IN (
 'dir /b /ad "%destdir%\%year%\%~1*" 2^>nul'
 ) DO IF DEFINED copied (ECHO %1 NOT copied to duplicate destination "%destdir%\%year%\%%b\"
 ) ELSE (
  SET "copied=%destdir%\%%b\"
  ECHO(                    XCOPY /s "%sourcedir%\%~1\*" "%destdir%\%year%\%%b\"
 )
)
IF DEFINED copied (ECHO %1 WAS copied to destination "%copied%"
) else (ECHO %1 WAS NOT copied - no destination found)
GOTO :EOF

year now no longer contains just the year, but possibly the next lower directory level (project) if the filename provided contains a subproject.

Upvotes: 1

Related Questions