Link to home
Start Free TrialLog in
Avatar of BBG-BBGM
BBG-BBGMFlag for United States of America

asked on

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.
Avatar of BillDL
BillDL
Flag of United Kingdom of Great Britain and Northern Ireland image

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?
Avatar of BBG-BBGM

ASKER

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?
SOLUTION
Avatar of BillDL
BillDL
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
In the code above, set the following values:

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


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
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\adocument21.txt
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!

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 ;-)

BillDL

You are a gentleman. Thank you.
Avatar of AmazingTech
AmazingTech

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%!"
)

Open in new window

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.
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%!"
)

Open in new window

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.
OK. I had to add in making of the parent folder.

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%!"
)

Open in new window

ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
That worked like a charm!  Thanks to all for your great work!
OK. Great! Thanks for the grade.
Thank you BBG-BBGM