Copy files from a set of subfolders to a single folder, rename with original folder name

I have a set of xml files I need to collect in one location. All are in the same subdirectory structure, all have the same name:

h:\test\35001\
form.xml

h:\test\35027\
form.xml

h:\test\35033\
form.xml

I wish to copy each form.xml file that is in a specified list file (filelist.txt) to a new location h:\analysis and rename each with the name of the originating directory. (Not every subdir in the original location has a file I want.) All files are located on a Win 2008 fileserver.

So the final result is to be:

h:\analysis\
35001.xml
35027.xml
35033xml
etc.

I've looked at many batch files, but my DOS skills have been lost over the many years of doing other things.....can an expert help?

taxbusterAsked:
Who is Participating?
 
Paul TomasiConnect With a Mentor Commented:
ReneGe

>> %~dp0, means, "drive\path"

Just a small correction:

   %~dp0, means, "drive\path\"

(don't forget the trailing '\')
0
 
ReneGeCommented:

@ECHO OFF

SET BaseFolder=%~dp0Test
SET TargetFolder=%~dp0Analysis

ECHO ^>Creating test files and folders
	FOR %%A IN (35001,35027,35033) DO (
		IF NOT EXIST "%BaseFolder%\%%A" MD "%BaseFolder%\%%A"
		ECHO TEST>"%BaseFolder%\%%A\form.xml"
	)
	IF NOT EXIST "%TargetFolder%" MD "%TargetFolder%"
ECHO ^>The files and folders are now created
ECHO.
PAUSE
ECHO.
ECHO.

ECHO ^>COPYING FILES TO TARGET FOLDER
	FOR /D %%A IN ("%BaseFolder%\*.*") DO (
		ECHO "%TargetFolder%\%%~nA.xml"
		COPY /Y "%%A\form.xml" "%TargetFolder%\%%~nA.xml"
	)
ECHO.
PAUSE

Open in new window

0
 
ReneGeCommented:
Note that the test folders, files and destination will be subdirectories of where your batch file will be.

Delete lines from 6 to 16 for production.

Cheers,
Rene
0
Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

 
Bill PrewCommented:
Will filelist.txt contain the full path to the file?

~bp
0
 
taxbusterAuthor Commented:
@billprew: As filelist.txt will be created by me (or some other human device) yes, it could, or not, depending on what is easiest. The list of files will likely only change over a period of some months, but this is the only way I can find to import these XML files into one spot so a simple import of the data in those into Excel is possible. (That may be done by somebody with little or no Excel experience so simplifying the whole process is important to me!)

I would very much prefer to operate from a file rather than burying the list in the batch file (as ReneGe has suggested as there are about 40-50 files to pull). Gets a little tricky if they're all text in a batch file!
0
 
Paul TomasiCommented:
billprew, texbuster, do you need some help with this one?
0
 
ReneGeCommented:
Here is a modified version of my script, considering the FileList.txt

The way I did it, is not streight forward, but it works as demended.

Please wait to close this question as I am currious to see Steve's, Bill or Paul's version with a more streight forward approach; something like:
FOR /F "usebackq delims=" %%A in ("FileList.txt") DO COPY /Y "%%~A" "h:\analysis\%Number%.xml

Note that this command line will not work as is.

Don't be shy to split points.

Cheers,
Rene
@ECHO OFF

SET BaseFolder=%~dp0Test
SET TargetFolder=%~dp0Analysis
SET FileList=%~dp0FileList.txt

ECHO ^>Creating test files and folders
	IF EXIST "%FileList%" DEL "%FileList%"
	FOR %%A IN (35001,35027,35033) DO (
		IF NOT EXIST "%BaseFolder%\%%A" MD "%BaseFolder%\%%A"
		ECHO TEST>"%BaseFolder%\%%A\form.xml"
		ECHO "%BaseFolder%\%%A\form.xml">>"%FileList%"
	)
	IF NOT EXIST "%TargetFolder%" MD "%TargetFolder%"
ECHO ^>The files and folders are now created
ECHO.

ECHO ^>COPYING FILES TO TARGET FOLDER
	FOR /D %%A IN ("%BaseFolder%\*.*") DO (
		ECHO "%TargetFolder%\%%~nA.xml"
		FINDSTR "%%~nA" "%FileList%" >NUL && COPY /Y "%%A\form.xml" "%TargetFolder%\%%~nA.xml"
	)
ECHO.
PAUSE

Open in new window

0
 
ReneGeCommented:
Here is the production script.

@ECHO OFF

SET BaseFolder=%~dp0Test
SET TargetFolder=%~dp0Analysis
SET FileList=%~dp0FileList.txt

ECHO ^>COPYING FILES TO TARGET FOLDER
	FOR /D %%A IN ("%BaseFolder%\*.*") DO (
		ECHO "%TargetFolder%\%%~nA.xml"
		FINDSTR "%%~nA" "%FileList%" >NUL && COPY /Y "%%A\form.xml" "%TargetFolder%\%%~nA.xml"
	)
ECHO.
PAUSE

Open in new window

0
 
taxbusterAuthor Commented:
ReneGe: That seems to work flawlessly! I'll leave the question open for the time being - now will be able to test on the production system and see if my overall plan will actually work.

Thanks - Don
0
 
ReneGeCommented:
You'r welcome.
Let see if my fellow experts have a better alternative.
Cheers,
Rene
0
 
Bill PrewCommented:
No thanks Paul...

~bp
0
 
Bill PrewCommented:
Give this a try, I think it should do what you want.

@echo off
for /F "usebackq tokens=*" %%A in ("FileList.txt") do (
  for %B in ("%~dpA.") do (
    copy /Y "%%~A" "h:\analysis\%%~nB.xml"
  )
)

Open in new window

~bp
0
 
ReneGeCommented:
@Bill: In line 3, is only one % volontary?
0
 
Bill PrewCommented:
Thanks Rene, good catch, was testing at a command line, then pasted some in for the batch, forgot that adjustment.  So it should be:
@echo off
for /F "usebackq tokens=*" %%A in ("FileList.txt") do (
  for %B in ("%%~dpA.") do (
    copy /Y "%%~A" "h:\analysis\%%~nB.xml"
  )
)

Open in new window

~bp
0
 
ReneGeCommented:
Line 3:
for %%B in ("%%~dpA.") do (
0
 
ReneGeCommented:
@taxbuster

Bill's script is better than mine, tested it and works faster.

It is the streight forward version I was takling about :)

Cheers,
Rene
0
 
ReneGeCommented:
Here Bill's version added to my test script.

@ECHO OFF

SET BaseFolder=%~dp0Test
SET TargetFolder=%~dp0Analysis
SET FileList=%~dp0FileList.txt

ECHO ^>Creating test files and folders
	IF EXIST "%FileList%" DEL "%FileList%"
	FOR %%A IN (35001,35027,35033) DO (
		IF NOT EXIST "%BaseFolder%\%%A" MD "%BaseFolder%\%%A"
		ECHO TEST>"%BaseFolder%\%%A\form.xml"
		ECHO "%BaseFolder%\%%A\form.xml">>"%FileList%"
	)
	IF NOT EXIST "%TargetFolder%" MD "%TargetFolder%"
ECHO ^>The files and folders are now created
ECHO.

ECHO ^>COPYING FILES TO TARGET FOLDER
for /F "usebackq tokens=*" %%A in ("%FileList%") do (
	for %%B in ("%%~dpA.") do (
	ECHO Copying %%~nB.xml
	copy /Y "%%~A" "%TargetFolder%\%%~nB.xml"
  )
)

ECHO.
PAUSE
exit

Open in new window

0
 
taxbusterAuthor Commented:
OK - something is mucked up: The ReneGe script (ID: 36985697) above worked fine. Incorporating Bill's into it fails (ID 36987217):
Copying .xml
The system cannot find the file specified.

I suspect a path error? I've deleted the setup and creation of the files/folders - those are already in place, and the batch file runs from the same root as the source and target folders.

Personally, I'm totally happy with the original script unless there is a "cleaner" way to do it.
0
 
Bill PrewCommented:
In the filelist, you need the full path to the files, do you have that (I suspect not).

~bp
0
 
ReneGeCommented:
Could you please provide a sample of your FileList.txt?
0
 
taxbusterAuthor Commented:
OK - the last part confused me a bit -- I've added the path to each item in filelist.txt but all the files concatenated into one file - "test.xml".

I've simply adjusted the last line slightly, and it seems to work a treat. Code I'm now using is below, and is a bit of both ReneGe's and billprew's:

 
@ECHO OFF

SET BaseFolder=%~dp0Test
SET TargetFolder=%~dp0Analysis
SET FileList=%~dp0FileList.txt



ECHO ^>COPYING FILES TO TARGET FOLDER
for /F "usebackq tokens=*" %%A in ("%FileList%") do (
	for %%B in ("%%~dpA.") do (
	ECHO Copying %%~nB.xml
	copy /Y "%%A\form.xml" "%TargetFolder%\%%~nA.xml"
  )
)

ECHO.
PAUSE
exit

Open in new window

0
 
Bill PrewCommented:
It appears that filelist.txt actually contained the parent folders, not the actual file names then?

You understand our confusion based upon "I wish to copy each form.xml file that is in a specified list file (filelist.txt)".

This is why is always best to provide a sample of any files involved for reference.

Glad you got something working.

~bp
0
 
ReneGeCommented:
Why did you need to add the paths of each XML files? Is it because you do not to move all them to the target folder, but rather only the ones you choose?
0
 
ReneGeCommented:
I feel that my previous question could be confusing.

Why not just copying all the FORM.XML files to the destination folder, in your required format?

Is it because you what to manually choose the files to be copied, by putting them to the FileList.txt?

Yep, this one sounds better.

Cheers,
Rene
0
 
taxbusterAuthor Commented:
Rene and Bill:

Because all the original files have the same name (form.xml) but different locations (e:\test\35001; e:\test\35027 etc) copying all of the files to a single location will fail unless I change their names. The number also indicates the form number used in the originating application. So, at the end of the day, I want all of those "form.xml" files in one subdir (e:\analysis in my test scenario) as distinct files: 35001.xml, 35027.xml etc.

From there it is easy to do a VB XML import (or a manual one) to a single Excel file which I have premapped to pick only the fields I wish to document.

I would PREFER not to have the fully qualified path in filelist.txt as I can just extract the list of form numbers (and therefore) subdirs from another Excel file, drop them into the text file filelist.txt and then run the batch file against it. Adding the path is a simple step of concatenation however in Excel.

I added it because I thought it was required per the comment above:
"In the filelist, you need the full path to the files, do you have that (I suspect not).

~bp"


As well, though I have about 150 subdirs, only about 60 are currently in use - the others are either old forms, development or test forms, so I don't care about them. They will change slightly from time to time, but not often.

Having written the above, something just occurred to my (aging - hah!) brain. In the following lines should I have actually added the full path?
SET BaseFolder=%~dp0Test
SET TargetFolder=%~dp0Analysis
SET FileList=%~dp0FileList.txt


ie: SET BaseFolder=%~dp0e:\Test etc

0
 
ReneGeCommented:
...should I have actually added the full path? = Yes

Also, Since you could just have the folder number in FileList.txt. We'll slightly adapt the script.

Like:
35001
35027
35033
0
 
taxbusterAuthor Commented:
That would be ideal!
0
 
ReneGeConnect With a Mentor Commented:
Try this

@ECHO OFF

SET SourceFolder=H:\Test
SET TargetFolder=H:\Analysis
SET FileList=%~dp0FileList.txt

ECHO ^>COPYING FILES TO TARGET FOLDER
FOR /F "usebackq tokens=*" %%A in ("%FileList%") do (
	ECHO Copying %%A
	COPY /Y "%SourceFolder%\%%A\form.xml" "%TargetFolder%\%%A.xml"
)

ECHO.
PAUSE
EXIT

Open in new window

0
 
Bill PrewCommented:
@taxbuster

In terms of locating the files to copy, why not just copy all form.xml files from under the parent directory, or will there be folders under h:\test that don't want to be copied?  We could still rename them to their parent folder name, just wondering if the TXT file with the folder names is truly needed, or could all folders be processed?

~bp
0
 
taxbusterAuthor Commented:
@billprew:

Sadly, it's only a subset that should be grabbed as ALL of the just-grabbed files need to be imported into the final Excel destination. Separating the "required" from the "not required" files is almost impossible to do at the import stage, so doing it from a file list seemed like the easiest approach. And, I can generate that file list from another table by simply filtering the 'active' forms - two steps and I have my list.

It doesn't really matter to me, but eventually someone less capable will be doing the work and I want to make it as easy for them as it can be.
0
 
Bill PrewCommented:
Okay, fair enough.  Seems like you have a couple of viable solutions then at this point.  For completeness, if the textfile only contains the parent directory name where the xml file resides, then my earlier script would become:

@echo off
set BaseDir=c:\base
set DestDir=d:\dest
for /F "usebackq tokens=*" %%A in ("FileList.txt") do copy /Y "%BaseDir%\%%A\form.xml" "%DestDir%\%%A.xml"

Open in new window

~bp
0
 
ReneGeCommented:
And of corse, the "FileList.txt" is set to be in the same directory as the batch file, because %~dp0, means, "drive\path" of the running batch file (0) (%~dp0).
0
 
Bill PrewCommented:
@taxbuster

Did one of the solutions work for you, or do you still need more info?

~bp
0
 
Paul TomasiCommented:
ReneGe

Oops! Posted in haste.

After giving it a liitle thought... you are right afterall. Apologies. Of course, the \ is part of the path (which you already stated) - worth pointing out nevertheless.
0
 
ReneGeCommented:
@paultomasi:

It's always nice to have you arround.

It's good that you pointed this out.  In my explanation in 36997096, I should have in deed added \ at the end.

Cheers!

0
 
ReneGeCommented:
@taxbuster:

How is your project doing so fare? Do you still need help with this question?

Cheers,
Rene

0
 
Paul TomasiCommented:
Thank you ReneGe... !!
0
All Courses

From novice to tech pro — start learning today.