0

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% 
Magoo
  • 77,302
  • 8
  • 62
  • 84
UIsa
  • 11
  • 2

1 Answers1

0

It's normal to follow the @echo off line with setlocal. This makes sure that any variables altered or created in the batch file are not maintained in the cmd session'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 syntax set 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 to drive. 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 by xcopy.

So I'll restate the problem as "copy all directories that have a name ending 100"

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the directories and filenames are names
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.

SET "sourcedir=u:\your files"
SET "destdir=u:\your results"

FOR /f "delims=" %%e IN (
 'dir /b /s /ad "%sourcedir%\PWD\*" ^|findstr /e "100"'
 ) DO (
 SET "dirname=%%e"
 SET "dirname=!dirname:*\PWD\=!"
 ECHO XCOPY "%%e\*" "%destdir%\!dirname!\"

)

GOTO :EOF

Always verify against a test directory before applying to real data.

The setlocal enabledelayedexpansion invokes delayedexpansion mode, where within a code block (parenthesised sequence of lines) !var! is the run-time value of var (as var is changed) and %var% is the value that var contained 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 dir command lists all directories (/ad) in basic form (/b) that is, name only - no size, date, etc. The /s extends the scan to subdirectories also.

The dir output is piped to findstr (the caret escapes the pipe to show that it is part of the command to be executed, not of the for) which filters the dir list for (directorynames) which /e end "100".

The for/f assigns each line of the result to %%e. The delims=" ensures the entire line is assigned to %%e(in case%%e` contains separators like Space)

%%e thus contains something like U:\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 the xcopy command. Batch cannot substring a metavariable like %%e directly, so we assign %%e to a user-variable dirname (which is therefore changing within the loop, so we need to use !dirname! to acess it's run-time value) and the following set removes all characters up to and including \PWD\. (See set /? from the prompt for documentation)

Then it's just a matter of performing the xcopy. Note that I've added an echo keyword to "disarm" the xcopy so that the xcopy command is merely listed to the console instead of being executed. Once you've verified that the command is correct, remove that echo to actually execute the xcopy.

The destination of the xcopy is </kbd> which tells xcopy that the destination is a directory, and to create it if it does not exist.

Add >nul to the xcopy command to suppress the report if you want.

Magoo
  • 77,302
  • 8
  • 62
  • 84