Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have a file hierarchy like this:

RootDir
  /A
    /fileA.txt
  /B
    /C
       /fileC.txt
    /fileB.txt
  /otherFile1.txt
  /otherFile2.txt

I'd like to copy only the subdirs (i.e. A, B) and everything under them (meaning I want everything copied EXCEPT otherFile1.txt and otherFile2.txt).

There are a lot more than 2 dirs and 2 files under the root dir so I'd rather not specify each one by name.

Any suggestions?

share|improve this question
    
is powershell solution acceptable? in powershell this will be one-liner. in pure batch - might be a bit more complicated. –  mnmnc Feb 25 '13 at 14:44
2  
The title does not match the question. The answer to the question in the title is xcopy /t; the answer to the question in the question body is more involved. –  Michael Kjörling Feb 25 '13 at 14:55
    
I agree. I suppose this is one of those cases where you are actually better off doing it in xcopy than Robocopy –  Austin ''Danger'' Powers Feb 25 '13 at 14:58
add comment

6 Answers

up vote 2 down vote accepted

You can use a combination of for /f, xcopy and dir to accomplish this task:

cd SOURCE
for /F "delims=" %a in ('dir /B /AD') do @xcopy /E "%a" "DESTINATION\%a\"

How it works:

  • Once you enter the SOURCE directory, the command dir /B /AD lists all directories (/AD), one by line (/B).

  • for /F "delims=" %a in ('...') do goes through the output of the command ..., sets the variable %a to the next line of output and executes whatever follows do.

    Here, delims= makes sure the variable holds the entire line's content. Without it, %a would only hold the characters up to the first space.

  • xcopy /E "%a" "DESTINATION\%a\" copies the directory currently specified in %a into a folder of the same name in the directory DESTINATION. The /E switch causes the directory's contents to be copied as well.1

    Specifying the directory's name in the destination is essential. Without it, fileA.txt would get copied to DESTINATION\fileA.txt (rather than DESTINATION\A\fileA.txt).

    The trailing backslash is used to indicate that %a is the name of a directory, not a file. The double quotes are necessary to handle directory names containing spaces properly.

If this command is going to be used inside a batch file, all percent signs have to be escaped with a second percent sign, i.e., %a becomes %%a.


1 /E copies empty directories as well. If this is not desired, you can use /S instead.

share|improve this answer
    
Great explanation. Thanks for taking the time to write it! –  Cristi Diaconescu Feb 26 '13 at 9:37
add comment

Similar to the Dennis and David Ruhmann answers, but using a FOR /D loop instead of FOR /F.

for /d %F in (rootFolderPath\*) do @xcopy /e /i "%F" "destinationPath\%~nxF"
share|improve this answer
    
It'd be great if you could explain the difference between /F and /D flags (for the sake of completion; I know for /? covers that). More importantly, what does the weird-looking substitution (?) pattern at the end do? –  Cristi Diaconescu Feb 26 '13 at 9:40
    
All is explained in the help: /F parses text file contents, or parses a string, or parses the output of a command. /D iterates directories. The pattern at the end is explained at the very bottom of the help. %~nxF expands the value of %F into the name and extension, ignoring drive and path. –  dbenham Feb 26 '13 at 12:12
add comment

The best way I can think of is using Robocopy's "/create" switch, which copies the entire folder structure only, and "0 length files only" -which I'm sure would lead to all your files being excluded

Robocopy /e /create \(source path of folder A) \(destination path)

Robocopy /e /create \(source path of folder B) \(destination path)

You could also (if they are all the same file types, or a small number of known file types) use the "Exclude File" "/xf" switch and wildcard out the file types, like this:

Robocopy /e (source path of folder A) (destination path) /xf *.txt

Robocopy /e (source path of folder B) (destination path) /xf *.txt

share|improve this answer
2  
how will this prevent copying files under root directory? –  mnmnc Feb 25 '13 at 14:48
    
Wouldn't this fail to copy the files under the sub-directory? –  David Feb 25 '13 at 15:03
    
Not any more. I just added the /e ("copy subdirectories, including empty ones") switch. –  Austin ''Danger'' Powers Feb 25 '13 at 15:04
    
I think it's not necessary to give my answer a thumbs down just because it's not the quickest solution. It does all the work- doesn't leave the OP having to manually delete the files afterwards, unlike the other answer. –  Austin ''Danger'' Powers Feb 25 '13 at 15:06
    
The OP doesn't want to copy any files in the root of the source directory but this appears to do that. –  Nicole Hamilton Feb 25 '13 at 15:29
add comment

This sort of thing is easy with a Unix shell. Here's how you might do it with my own Hamilton C shell (including the free version. You could do something similar with Cygwin bash though it might a little harder. This will copy all the subdirectories but only the subdirs of RootDir and their contents to DestinationDir.

cd RootDir
cp ``ld -1`` DestinationDir

ld is an alias for ls that lists only directories. The -1 option means list the output in a single column, one entry per line. The double backquotes mean line-at-a-time command substitution, ensuring this will work even if some the subdir names contain spaces.

Here's a screenshot showing how it works. Notice that it copies everything except the hello.txt file in the root. All the subdirs and their contents are copied. The ls -r option means recursive.

Copy only subdirs using Hamilton C shell

share|improve this answer
add comment

Native Windows CMD solution. Copy only the subfolders (and their contents) from a RootDir.

for /f "delims=" %%A in ('dir RootDir /a:d /b') do xcopy %%A DestDir /e /i
share|improve this answer
add comment

As pointed out by another user in the comments, the shortest solution which accomplishes what the OP is trying to do is simply:

xcopy /t /e

share|improve this answer
    
The OP wants to copy the contents of the subdirs as well, but xcopy /t only copies non-empty directories, not their contents. –  Nicole Hamilton Feb 25 '13 at 15:26
    
Thanks Nicole- I've added the "/e" switch ("copy Empty directories and subdirectories") so it finally does what the OP wants. No room for improvement now! –  Austin ''Danger'' Powers Feb 25 '13 at 15:31
    
This still doesn't copy any of the contents of the subdirs. As I read the OP, I think the only files to be omitted are the files at the top. Any other files lower in the tree should be copied. –  Nicole Hamilton Feb 25 '13 at 15:36
    
I think the OP should clarify whether he wants directores AND files (as indicated in the body) or to exclude files (as indicated in the title). –  Austin ''Danger'' Powers Feb 25 '13 at 15:40
    
I have the broad lines of the question in the title, and the details and disambiguation in the question's body. If you can find a more descriptive (and still succint) title, by all means, edit the title. –  Cristi Diaconescu Feb 25 '13 at 20:16
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.