# Move only folders (and contents) which match a string?

I have a very large folder structure and need to find all subfolders with a certain keyword in them and then move those subfolders (including contents) to a new location.  For instance, say I have the following folders containing files of various types:

source\file1\bar\foo
source\file2\file3\bar\stuff
source\file3\foobar

Now, I want to move all folders with the word "foo" in them from 'source' to 'destination'.  The result I want is:
source\file2\file3\bar\stuff

destination\file1\bar\foo
destination\file3\foobar

I was looking at robocopy and xcopy but neither seem to give me the ability to move a folder and its contents based on search criteria without affecting nonmatching folders in the source location.  Any ideas?  Maybe I am missing something painfully obvious.
LVL 1
###### Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Commented:
This should be easy enough to do using a FOR command that parses through the output from a filtered DIR listing of Folders in the source and runs the xcopy command sequentially for each folder name.  Something along these lines perhaps (don't use it, it's just an untested example off the top of my head):

@echo off
set SourcePath=C:\Some_Folder
set DestPath=G:\Some_Folder

for /f "tokens=* delims=" %%a in ('dir /on /ad /b /s "%SourcePath%" ^| find /i "foo"') do xcopy /switches "%%a\" "%DestPath%\%%a"

where the DIR listing for folder names only is searched for those with (case insensitive) "foo" in the name, and the resultant listing is used as the folder names for the xcopy command to "move" to the destination sequentially as it reads through the listing.

Before creating a proper and tested batch file, however, it is very important to know how you would wish to handle a folder with "foo" in the name when it is a sub-folder of a folder WITHOUT "foo" in the name, or where the folder WITH the "foo" in its name also has one or more SUB-Folders NOT containing "foo" in the names.

Are you seeking to recreate the same folder hierarchy as is in the Source path, or do you want to flatten it completely so that the Destination contains ONLY the matching folder names and any loose files in each folder, BUT NOT sub or master folders that DO NOT contain "foo" in the names?

As an example, say you have the following folders in the source:

C:\Folder1\Sub-Folder1
C:\Folder1\Sub-Folder1\Foo_Files1
C:\Folder1\Sub-Folder1\Foo_Files2
C:\Folder1\Sub-Folder1\Foo_Files2\Some_Other_Folder
C:\Folder1\Sub-Folder1\Other_Files\Foo_Files3\Stuff
C:\Folder1\Sub-Folder1\Other_Files\Foo_Files3\Stuff\Scripts

Would you want:
"Some_Other_Folder" copied to the destination still as a sub-folder of "Drive:\Folder1\Sub-Folder1\Foo_Files2"
OR would you just want to copy the "Foo_Files2" folder MINUS the sub-folder named "Some_Other_Folder"?

Similarly, would you want the "Foo_Files3" folder copied on its own just with files in it, or have the master folder copied to the destination with "Foo_Files3" still as a sub-folder, and also copy any sub-folders and contents to the destination maintaining the original folder structure?

Flatten folders or maintain folder hierarchy?
0
Author Commented:
BillDL:
Thanks for the response.  I am looking to move the matching subfolders (including any subfolders regardless of name) to the destination with the entire original folder path.  Given your example (I modified it to show other outcomes):
C:\Folder1\Sub-Folder1
C:\Folder1\Sub-Folder1\abc
C:\Folder1\Sub-Folder1\Foo_Files1
C:\Folder1\Sub-Folder1\Foo_Files2
C:\Folder1\Sub-Folder1\Foo_Files2\Some_Other_Folder
C:\Folder1\Sub-Folder1\Other_Files\def
C:\Folder1\Sub-Folder1\Other_Files\def\stuff
C:\Folder1\Sub-Folder1\Other_Files\Foo_Files3\Stuff
C:\Folder1\Sub-Folder1\Other_Files\Foo_Files3\Stuff\Scripts

After running with 'SourcePath=C:\Folder1' and 'DestPath=G:\Folder2'  and keyword of 'foo' I would want to end up with:
C:\Folder1\Sub-Folder1
C:\Folder1\Sub-Folder1\abc
C:\Folder1\Sub-Folder1\Other_Files\def
C:\Folder1\Sub-Folder1\Other_Files\def\stuff

G:\Folder2\Sub-Folder1\Foo_Files1
G:\Folder2\Sub-Folder1\Foo_Files2
G:\Folder2\Sub-Folder1\Foo_Files2\Some_Other_Folder
G:\Folder2\Sub-Folder1\Other_Files\Foo_Files3\Stuff
G:\Folder2\Sub-Folder1\Other_Files\Foo_Files3\Stuff\Scripts

Does this help?
0
Commented:
Yes it does, thanks.

I will create a test source and try to achieve what you want done using XCOPY.
0
Commented:
This was a tough one.... Phew!!

Rename the SOURCE, DESTINATION and FILESPEC values. DO NOT include trailing '\' (backslash) characters on the end of SOURCE nor DESTINATION.

copy and paste the code into Notepad and save it as MOVETREE.BAT. Then, fire up a DOS session and enter the following command:

MOVETREE

@echo off
setlocal enabledelayedexpansion

set source=c:\source
set destination=c:\destination
set filespec=foo

for /f "tokens=*" %%a in ('dir /ad /b /s "%source%"') do (
set folder=%%~nxa
set folder=!folder:%filespec%=!
if not "!folder!"=="%%~nxa" (
set s=%%a
set s=!s:%source%=!
for /f "tokens=1 delims=\" %%b in ('echo !s!') do (
move "%source%\%%b" "%destination%\%%b"
)
)
)
0
Commented:
In the code above, set the following values:

set source=c:
set destination=g:
set filespec=foo

0
Commented:
Sorry... I see c:\folder1 is your source and g:\folder2 is your destination therefore your settings should be as follows:

set source=c:\folder1
set destination=g:\folder2
set filespec=foo
0
Author Commented:
t0t0:
Close, but not quite.  I ran the script with:
set source=d:\folder1
set destination=d:\folder2
set filespec=bulletin

On the following folder structure:
D:\Test1\folder1
D:\Test1\folder1\folder11
D:\Test1\folder1\folder12
D:\Test1\folder1\folder12\folderbulletin12
D:\Test1\folder1\folder12\folderno12
D:\Test1\folder1\folder12\folderbulletin12\bulletinstuff
D:\Test1\folder1\folder12\folderbulletin12\stuff
D:\Test1\folder2
D:\Test1\folder2\bulletindocument21.txt
D:\Test1\folder2\bulletinfiles21
D:\Test1\folder3
D:\Test1\folder3\folder31
D:\Test1\folder3\folder31\folder32
D:\Test1\folder3\folder31\folder32\afile.zip
D:\Test1\folder4
D:\Test1\folder4\folder41
D:\Test1\folder4\folder41\folder42
D:\Test1\folder4\folder41\folder42\bulletin42.psd

I ended up with:
d:\Test1\folder3
d:\Test1\folder3\folder31
d:\Test1\folder3\folder31\folder32
d:\Test1\folder3\folder31\folder32\afile.zip
d:\Test1\folder4
d:\Test1\folder4\folder41
d:\Test1\folder4\folder41\folder42
d:\Test1\folder4\folder41\folder42\bulletin42.psd

So far so good, since I don't mind if a filename has the string 'bulletin' in it... but the destination has unintended content:
d:\Test2\folder1
d:\Test2\folder1\folder11   <-- This one does not match
d:\Test2\folder1\folder12
d:\Test2\folder1\folder12\folderbulletin12
d:\Test2\folder1\folder12\folderno12  <-- This one does not match
d:\Test2\folder1\folder12\folderbulletin12\bulletinstuff
d:\Test2\folder1\folder12\folderbulletin12\stuff
d:\Test2\folder2
d:\Test2\folder2\adocument21.txt  <-- This one does not match
d:\Test2\folder2\bulletindocument21.txt  <-- File, not folder matching
d:\Test2\folder2\bulletinfiles21

It seems your script is copying the entire folder one level below where the folder matching 'bulletin' is appearing.  Great start though!

0
Commented:
Hee, hee.  I should have done this during the night when t0t0 was in bed sound asleep.  Good script so far t0t0.  I gave up trying xcopy.  I was using the /T switch just to try and create the empty folder structure in the destination before testing for real, but I was having difficulty maintaining the master folder in the structure when using %%~nxA.  I had just started off with a not-dissimilar idea using MOVE, but your script was written while mine was still conceptual.

I think I'll leave you to it t0t0.  You love this type of challenge, and so do I, but I need to have some dinner before going out to work.  You have the rest of the night after all essential domestic chores are done ;-)

0
Commented:
BillDL

You are a gentleman. Thank you.
0
Commented:
Give this a try.
@echo off
setlocal enabledelayedexpansion
set source=d:\folder1
set destination=d:\folder2
set filespec=bulletin

for /f "tokens=*" %%a in ('dir /ad /b /s "%source%\*%filespec%*"') do if exist "%%a" (
Set Found=%%a
move "%%a" "!Found:%source%=%destination%!"
)

0
Author Commented:
AmazingTech:
Getting close with that one but it is not working.  It looks like line 9 is taking the path in %Found% and substituting the %source% for %destination% but that is not working.  Here is what I get during output:

D:\>if exist "d:\Test1\folder2\bulletinfiles21" (
Set Found=d:\Test1\folder2\bulletinfiles21
move "d:\Test1\folder2\bulletinfiles21" "!Found:d:\Test1=d:\Test2!"
)
The system cannot find the path specified.
0 file(s) moved.

So I guess we need to figure out how to get string substitution to work with variables?  I suppose I could hard-code it for now just to get it to work... let me know if you have any ideas.
0
Commented:
Hmm.. The replace should work. Do you have a destination folder D:\Test2?
Here's an echo of the source and destination.
@echo off
setlocal enabledelayedexpansion
set source=d:\folder1
set destination=d:\folder2
set filespec=bulletin

for /f "tokens=*" %%a in ('dir /ad /b /s "%source%\*%filespec%*"') do if exist "%%a" (
Set Found=%%a
Echo Source=%%a
Echo Destination=!Found:%source%=%destination%!
Echo Moving "%%a" "!Found:%source%=%destination%!"
move "%%a" "!Found:%source%=%destination%!"
)

0
Commented:
Hello AmazingTech....

My attention was redirected for a little whle however, I've returned and noticed you've joined us. I'm currently working on a solution however, please feel free to muck in.
0
Commented:

Add /y to the move if you want it to overwrite without prompting.
@echo off
setlocal enabledelayedexpansion
set source=c:\documents and settings\gordon\at
set destination=c:\folder2
set filespec=itunes

for /f "tokens=*" %%a in ('dir /ad /b /s "%source%\*%filespec%*"') do if exist "%%a" (
Set Found=%%a
Set Parent=%%~dpa
Echo Source=%%a
Echo Destination=!Found:%source%=%destination%!
Echo Parent="!Parent:%source%=%destination%!"
If not exist "!Parent:%source%=%destination%!" MD "!Parent:%source%=%destination%!"
Echo Moving "%%a" "!Found:%source%=%destination%!"
move "%%a" "!Found:%source%=%destination%!"
)

0
Commented:
Seems to work fine as long as the folders do not already exists.

c:\Test1\folder1\folder12\folderbulletin12

d:\Test2\folder1\folder12\folderbulletin12

It will move c:\Test1\folder1\folder12\folderbulletin12 to:
d:\Test2\folder1\folder12\folderbulletin12\folderbulletin12

The best might be to create the folder and then move to the parent. For some reason my machine is giving me Access is denied. I'm not too sure if it is just my machine. Maybe someone can try this as see if they get the same result.

I'll leave out the /y from

move "%%a" "!Parent:%source%=%destination%!"
@echo off
setlocal enabledelayedexpansion
set source=d:\folder1
set destination=d:\folder2
set filespec=bulletin

for /f "tokens=*" %%a in ('dir /ad /b /s "%source%\*%filespec%*"') do if exist "%%a" (
Set Found=%%a
Set Parent=%%~dpa
Echo Source=%%a
Echo Destination=!Found:%source%=%destination%!
Echo Parent="!Parent:%source%=%destination%!"
If not exist "!Parent:%source%=%destination%!" MD "!Parent:%source%=%destination%!"
Echo Moving "%%a" "!Parent:%source%=%destination%!"
move "%%a" "!Parent:%source%=%destination%!"
)

0

Experts Exchange Solution brought to you by

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Author Commented:
AmazingTech:
It seems to be working this time!  Not sure why the replace was not working before... but it is now.  There will be no pre-existing folders in the destination location so I should be good.  i am going to run it on the data now and see how it goes.  Oh, I like the echos in there too because I can redirect out to logfile.

Will let you know how it goes.
0
Author Commented:
That worked like a charm!  Thanks to all for your great work!
0
Commented:
OK. Great! Thanks for the grade.
0
Commented:
Thank you BBG-BBGM
0
###### It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Windows Batch

From novice to tech pro — start learning today.