29

I'd like to use xcopy on a Windows machine to pull out all files with .png extension into a single directory.

I tried xcopy C:\folder\*.png /s C:\png\, but it is keeping the sub-directories inside \folder, (for example in C:\png, there is C:\png\a\b\c\img.png) which I don't want. I simply want all .png inside C:\png without it retaining the directory structure that was in C:\folder.

David Marshall
  • 7,200
  • 4
  • 28
  • 32
bobobobo
  • 5,302
  • 8
  • 46
  • 61
  • Try this- http://www.pcworld.com/article/2105149/gather-similar-files-from-multiple-folders-and-copy-them-in-one-simple-step.html – Swastik Padhi Oct 29 '15 at 09:39

3 Answers3

49

This can be done with good old for:

for /r C:\Folder %f in (*.png) do @copy "%f" C:\png

Nothing fancy.

Joey
  • 40,002
  • 15
  • 104
  • 126
  • 1
    It works! Care to explain what the `%f` is for? – bobobobo Nov 18 '10 at 19:13
  • It's the loop variable. – Joey Nov 18 '10 at 21:53
  • 5
    This didn't work for me, I got something to the effect of `f" was unexpected at this time`. Changing `%f` to `%%f` worked. However, I was running this in a batch file: *If you are using the FOR command at the command line rather than in a batch program, use just one percent sign: %G instead of %%G.* http://ss64.com/nt/for.html – ta.speot.is Dec 08 '14 at 00:27
  • 1
    Uhm, yes. That's expected and exactly as you quoted. Where I'd your confusion coming from? – Joey Dec 08 '14 at 22:00
  • There's a couple special variables you probably want to avoid when assigning them, like in this case, Joey set the variable designation of *f* for `%f`, which should be fine. Easiest way to make sure it's safe is use upper-case letters. `%%d` _might_ cause some issues, but `%%D` will be fine. Just make sure to use different variables for each nested for-loop used.= – kayleeFrye_onDeck Jan 20 '17 at 06:43
  • 1
    @kayleeFrye_onDeck: As far as I know there are no special variables. The only thing that springs to mind is that people unfamiliar with `for` may get confused about the two different `d` in things like `%~dd`. The `for` documentation suggests to use uppercase letters for variables to avoid confusion, but substitutions are still clearly distinguishable from the variable name, I think. – Joey Jan 20 '17 at 08:29
  • Honestly, I haven't bothered trying to create corner cases to break it. But yes, it's probably only for removing confusion. In general, I like to not even use the letters for batch parameter expansion, like `d`, `n`, `x`, `f`, `p`, `s`, `a`, `t`, and `z`, even upper-case. I also like to use only upper-case, because it makes it easier to spot the use of batch parameter expansion usage, at least for me. – kayleeFrye_onDeck Jan 20 '17 at 22:19
1

The batch file below is what I've ended up using for a bit more flexibility.
It builds on the accepted solution.

echo off

REM Copying all files with specified pattern recursively from source-directory and sub-folders into destination folder
REM Variables
REM   SRCFOLDER: Specifiy source directory. Search is recursivly done within that location. 
REM   SRCPATTERN: Search patter of one or multiple files, separated by space  (Used in "for in ()" type  loop
REM   DSTFOLDER: Specifiy destination directory. All files get copied into it.
REM   XCOPYOPTONS: Specify some copy options. /d only copies "newer" files, /y  suppresses overwrite prompts
setlocal
set DSTFOLDER=C:\temp\found\
set SRCFOLDER=C:\temp\test\
set SRCPATTERN=*.txt *.asc
set XCOPYOPTIONS=/d /y

for /R %SRCFOLDER% %%f in (%SRCPATTERN%) do xcopy "%%f" %DSTFOLDER% %XCOPYOPTIONS%
BmyGuest
  • 406
  • 3
  • 15
1

If you have cygwin installed, this would be a job for find:

cp `find /cygdrive/c/folder/* -name '*png'` /cygdrive/c/png/

(though that will have trouble if any of the filenames have spaces in them - you'll find some variant of a find command that will work in all circumstances though)

If you are running Vista, 2003 or 2008 then the less flexible but still useful "forfiles" is your friend. Something like:

FORFILES /P c:\folder\ /M *.png /S /C "cmd /c copy @file c:\png\"

Note: I've not tested either of the above commands, but in theory they should work...

David Spillett
  • 23,420
  • 1
  • 49
  • 69
  • +1 just verified that the FORFILES command works. I ran it twice and it copied the 2nd time w/out prompt, so I assume it just overwrites if it finds duplicates. – hyperslug Aug 08 '09 at 18:39