55

I'm a newbie, so bear with me...

I am trying to copy all .doc files that I have scattered throughout several subdirectories of one main directory into another directory using a batch file. I have managed to get a filelist.txt of all the files (there are hundreds) out of these directories that I want to copy using:

"C:\Main directory\sub directory" dir /b /s *.doc > "C:\Main directory\sub directory\filelist.txt"

What script would I use to xcopy those into one directory? Can I use some code that actually grabs those file names from filelist.txt and xcopies them?

For reference, I looked at the question below because it looked like it was doing what I want to do, but it didn't work for me.

Using xcopy to copy files from several directories to one directory

Also, I would really like to understand this concept, so please break down the code for me to tell me what each item does, or at least include a link that will explain it.

Community
  • 1
  • 1
  • 4
    Open the main directory in Windows Explorer, search for *.doc, select all (Ctrl+A) and copy/paste them to the new directory... I too initially went to cmd line for this, but the GUI solution is much quicker :) – Alex May 16 '13 at 00:05
  • I think you can just search *.doc and copy the results! – aliqandil May 13 '15 at 17:56
  • Use this answer to copy with subfolders https://stackoverflow.com/a/26421140/3197387 – Sisir Jul 30 '20 at 12:39
  • Use this answer to copy onli files https://stackoverflow.com/a/1224932/3197387 – Sisir Jul 30 '20 at 12:39

6 Answers6

66

In a batch file solution

for /R c:\source %%f in (*.xml) do copy %%f x:\destination\

The code works as such;

for each file for in directory c:\source and subdirectories /R that match pattern (\*.xml) put the file name in variable %%f, then for each file do copy file copy %%f to destination x:\\destination\\

Just tested it here on my Windows XP computer and it worked like a treat for me. But I typed it into command prompt so I used the single %f variable name version, as described in the linked question above.

Quill
  • 2,729
  • 1
  • 33
  • 44
Simeon Pilgrim
  • 22,906
  • 3
  • 32
  • 45
  • 1
    How would you address the problem if the exe name has spaces in it? – Euclid Oct 18 '12 at 16:28
  • 1
    @Euclid off the top of my head I'd change the final %%f to '%%f' to protect the spaces – Simeon Pilgrim Nov 05 '12 at 02:37
  • 5
    Thank you so much. How would we do this while retaining the folders that it came from? Example: keep the files in their folder names and tree structure – code Apr 01 '13 at 22:52
  • 1
    You have to be careful about files with identical names in different sub-folders. You will only have a copy of one of them. – Rabskatran Feb 27 '14 at 11:34
  • @user1456962 This can be done with a slightly more complicated script that saves the full path into a variable, replaces the characters in it with the new path, and then copies to the new path. Or, alternately, doing the recursion yourself using a batch file that calls itself and "hands in" the subdirectory currently being worked with. – ErikE Sep 05 '14 at 22:06
  • @android-user Retaining the folders that files come from is the default behaviour of `xcopy /S` command. Paths will be relative to the `source` filepath argument you supply. – Nigel Touch Feb 16 '15 at 10:22
  • so I accidentally ran this code: "for /R c:\source %%f in (*.dta) do move %%f x:\destination", which rather than move all my stata files into a new folder called "destination" as I wanted has pushed them all into a single file, of ambiguous type, called "destination". Woops. Any idea how I can recover the original files?! – David Zentler-Munro May 15 '18 at 10:29
59

Just use the XCOPY command with recursive option

xcopy c:\*.doc k:\mybackup /sy

/s will make it "recursive"

userJT
  • 11,486
  • 20
  • 77
  • 88
  • 14
    But if a file in is subfolder of `c:` then it also copies the subfolder and the `.doc` file .... instead of the file itself without the subfolder – JAN Jun 13 '15 at 09:09
  • Glad to give you some extra rep for this. I'd rather not script if there's a builtin that works well like this. – Kevin Anderson Aug 31 '17 at 16:41
6

Things like these are why I switched to Powershell. Try it out, it's fun:

Get-ChildItem -Recurse -Include *.doc | % {
    Copy-Item $_.FullName -destination x:\destination
}
Anubian Noob
  • 13,426
  • 6
  • 53
  • 75
user15071
  • 3,391
  • 8
  • 31
  • 31
  • 6
    You can actually just do `gci -rec -inc *.doc | cp -dest X:\Destination` since `Copy-Item` accepts pipeline input. Also you can probably get rid of `Get-ChildItem` completely and just do `Copy-Item -Recurse -Include *.doc -Destination C:\Destination` since `Copy-Item` has `-Recurse` and `-Include` as well. – Joey Aug 04 '09 at 00:03
  • does this retain the subfolder structure? seems not – Louis Rhys Jun 10 '13 at 02:11
  • 1
    @Joey First suggestion worked, second asked "*Supply values for the following parameters:*". Tried moving Recurse to end, then started looking at `Get-Help Copy-Item -Detailed`, then decided I should just try your first suggestion. ;) – ruffin Feb 05 '17 at 01:37
  • In order to move files one can modify Joey's solution like so `gci -rec -inc *.doc | mv -dest X:\Destination` – Rikijs Apr 13 '17 at 18:46
  • what if I wanna include multiple different different extensions? like png and jpg and gif? – xeruf Jul 29 '17 at 15:38
4

Brandon, short and sweet. Also flexible.

set dSource=C:\Main directory\sub directory
set dTarget=D:\Documents
set fType=*.doc
for /f "delims=" %%f in ('dir /a-d /b /s "%dSource%\%fType%"') do (
    copy /V "%%f" "%dTarget%\" 2>nul
)

Hope this helps.

I would add some checks after the copy (using '||') but i'm not sure how "copy /v" reacts when it encounters an error.

you may want to try this:

copy /V "%%f" "%dTarget%\" 2>nul|| echo En error occured copying "%%F".&& exit /b 1

As the copy line. let me know if you get something out of it (in no position to test a copy failure atm..)

Jay
  • 1,635
  • 16
  • 14
1

you can also use vbscript

Set objFS = CreateObject("Scripting.FileSystemObject")
strFolder = "c:\test"
strDestination = "c:\tmp\"
Set objFolder = objFS.GetFolder(strFolder)

Go(objFolder)

Sub Go(objDIR)
  If objDIR <> "\System Volume Information" Then
    For Each eFolder in objDIR.SubFolders       
        Go eFolder
    Next
    For Each strFile In objDIR.Files
        strFileName = strFile.Name
        strExtension = objFS.GetExtensionName(strFile)
        If strExtension = "doc" Then
            objFS.CopyFile strFile , strDestination & strFileName
        End If 
    Next    
  End If  
End Sub 

save as mycopy.vbs and on command line

c:\test> cscript /nologo mycopy.vbs
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
0

This can be done using this command:

for /r "C:\source" %f in (*.doc) do @copy "%f" "C:\destination"

you could also run these to make it simple

set source="C:\src"
set destination="C:\dest"
set extension=doc

for /r %source% %f in (*.%extension%) do @copy "%f" %destination%

In case you are willing to copy with file types parent folder name try using this command

xcopy "C:\src\*.doc" "C:\dest" /sy
Affes Salem
  • 1,303
  • 10
  • 26