I want to write a batch program to copy some deeply nested folders with the same suffix in this case 100,
It only copied all the folders but only one file in the top most folder (they are alphabetically arranged in the server) *100.bat was copied.
I want to copy all files in all folders with name_of_folder100.
Thanks for your Time.
This is my attempt:
@echo off
:: variables
set hour=%time:~0,2%
if "%hour:~0,1%"==" " set hour=0%time:~1,1%
set
set drive= E:\PWD_BACKUP_%date:~10,4%_%date:~4,2%_%date:~7,2%_%hour%_%time:~3,2%
set PWD_drive_100=E:\PWD_BACKUP_\PWD_100_%date:~10,4%_%date:~4,2%_%date:~7,2%_%hour%_%time:~3,2%
set backupcmd=xcopy /s /c /d /e /h /i /r /y
%backupcmd% "\\xx.xx.xx.xx\live_projects\PWD\*100" %PWD_drive_100%
It's normal to follow the
@echo offline withsetlocal. This makes sure that any variables altered or created in the batch file are not maintained in thecmdsession's environment when the batch ends.Use
set "var=value"for setting string values - this avoids problems caused by trailing spaces. Don't assign a terminal\, Space or"- build pathnames from the elements - counterintuitively, it is likely to make the process easier. If the syntaxset var="value"is used, then the quotes become part of the value assigned.The
set drive=...statement will include the space following the=in the value assigned todrive. This is probably of no consequence in the current situation, but may be significant for other batches.Other than the last 2 lines of code, there is a great deal of date/time-manipulation going on. We have to rely on your local knowledge here as the date/time format is user-dependent.
The overall problem is that
*cannot be used for directorynames. Logically, what you appear to want to copy from your description is...e_projects\PWD\*100\*, but that structure is not supported byxcopy.So I'll restate the problem as "copy all directories that have a name ending
100"Always verify against a test directory before applying to real data.
The
setlocal enabledelayedexpansioninvokesdelayedexpansionmode, where within a code block (parenthesised sequence of lines)!var!is the run-time value ofvar(asvaris changed) and%var%is the value thatvarcontained when the code block was parsed.Documentation: Stephan's DELAYEDEXPANSION link
We then establish the source and destination directories. I've posted my test directories, you would need to edit them to suit your particular circumstances.
The
dircommand lists all directories (/ad) in basic form (/b) that is, name only - no size, date, etc. The/sextends the scan to subdirectories also.The
diroutput is piped tofindstr(the caret escapes the pipe to show that it is part of the command to be executed, not of thefor) which filters thedirlist for (directorynames) which/eend "100".The
for/fassigns each line of the result to%%e. Thedelims=" ensures the entire line is assigned to%%e(in case%%e` contains separators like Space)%%ethus contains something likeU:\your files\PWD\sub 5\subsub 5\subsubsub\subsubsubsub100, so we need to remove the part up to\PWD\to get the subdirectory name in a format suitable for thexcopycommand. Batch cannot substring ametavariablelike%%edirectly, so we assign%%eto a user-variabledirname(which is therefore changing within the loop, so we need to use!dirname!to acess it's run-time value) and the followingsetremoves all characters up to and including\PWD\. (Seeset /?from the prompt for documentation)Then it's just a matter of performing the
xcopy. Note that I've added anechokeyword to "disarm" thexcopyso that thexcopycommand is merely listed to the console instead of being executed. Once you've verified that the command is correct, remove thatechoto actually execute thexcopy.The destination of the
xcopyis </kbd> which tellsxcopythat the destination is a directory, and to create it if it does not exist.Add
>nulto thexcopycommand to suppress the report if you want.