3

I have a text file containing a list of files and folders. What I want to do is use xcopy to replicate what is written in the text file. My text file looks like this:

"C:\FOLDER"  
"C:\FOLDER\FILE1.TXT"
"C:\FOLDER\FILE2.TXT"
"C:\FOLDER\FOLDER2"
"C:\FOLDER\FOLDER2\FILE3.TXT"

For a given output directory "C:\OUTPUT" I would like to replicate the entire structure, so:

"C:\OUTPUT\FOLDER"  
"C:\OUTPUT\FOLDER\FILE1.TXT"
"C:\OUTPUT\FOLDER\FILE2.TXT"
"C:\OUTPUT\FOLDER\FOLDER2"
"C:\OUTPUT\FOLDER\FOLDER2\FILE3.TXT"

How can I accomplish this? So far I have written a for loop that reads in each line of the file, but it copies all files if the line is a folder. What I want to do is only copy and create the files and folders that are mentioned in the text file.

@echo off
for /f "delims=] tokens=1*" %%a in (textfile.txt) do (
   XCOPY /S /E %%a "C:\OUTPUT"
)

Am I on the right track?

Thank you and best regards,

Andrew

Andrew
  • 293
  • 6
  • 14

1 Answers1

5

Yes, you are close. Just need to use the existing path as the appended destination path.

Update

@echo off
for /f "delims=" %%A in (textfile.txt) do if exist "%%~fA\*" (
    md "C:\Output\%%~pA"
    copy /y "%%~fA" "C:\Output\%%~pnxA"
)

Original

If %%A = "C:\Folder\Folder2\File3.txt", then %%~pA = Folder\Folder2

@echo off
for /f "delims=" %%A in (textfile.txt) do (
    md "C:\Output\%%~pA"
    if not exist "%%~fA\*" echo f | xcopy "%%~fA" "C:\Output\%%~pnxA" /y
)

The if not exist "%%~fA\*" makes sure to only copy the entry if it is not a directory. See Reference for more Techniques and Comments

Type in for /? at the command line to view a list of the variable modifiers. %%~A will remove the surrounding quotations (if any) from the variable.

Post about xcopy prompting issue. and fix #2.

Alternate Setup, since you most likely will not need the xcopy abilities.

@echo off
for /f "delims=" %%A in (textfile.txt) do (
    md "C:\Output\%%~pA"
    if not exist "%%~fA\*" copy /y "%%~fA" "C:\Output\%%~pnxA"
)
Community
  • 1
  • 1
David Ruhmann
  • 11,064
  • 4
  • 37
  • 47
  • Thank you David! Is there a way of making it so that it doesn't copy the contents of the folder? Basically I want it to copy the files mentioned in the text file even though there might be files present in the directory that aren't in the file. The rule I'm looking for is "if the line is a folder, create the folder and folder structure. If the line is a file, copy the file to the directory". The code above copies the entire folder content instead of just creating the folder. – Andrew Jan 22 '13 at 13:47
  • I am new to batch scripting so I have no idea what's going on! So %%~pA will retrieve the directory structure minus drive and filename. What does %%~A give me? Is the if condition that you mentioned above the snippet contained within it? I'm not sure how it performs the check... – Andrew Jan 22 '13 at 13:58
  • @Andrew Welcome to Batch Scripting. There will be many headaches. **`:)`** I have updated my answer and for almost any command at the command line you can use the `/?` help parameter to find out all sorts of useful information. Also see my answer here for some great online resources for batch scripting. http://stackoverflow.com/a/14431974/891976 – David Ruhmann Jan 22 '13 at 14:32
  • This version does not copy any files. `if not exist "%%~A\"` works but it asks me to specify whether the files are files or directories. I suppressed overwrite and directory specification prompts by using the /y and /i commands, but now it asks whether the files are files or directories. I'm so close! What an excellent script! – Andrew Jan 22 '13 at 14:38
  • @Andrew Unfortunately, that is a common problem with `xcopy`. See the post I added to my answer for multiple ways to fix the issue. 1. Use `copy` instead of `xcopy`. 2. Use `echo f | xcopy` to simulate f input. 3. Create a blank file before the xcopy command with `echo.>"%%~fA"`. I have added solution 2 to my answer, but any of them will work. – David Ruhmann Jan 22 '13 at 15:10
  • +1, although your one liner isn't exactly equivalent to the multi-lined version it is derived from. Particularly because of the `&&`: if the folder exists, `md` will terminate with a non-zero exit code and the subsequent command will not execute. Perhaps that was a typo and you actually meant to use `&` there. – Andriy M Jan 22 '13 at 15:37
  • Also, if you meant to suggest the one-liner for direct use at the command prompt, you should probably get rid of `@echo off` at the beginning and "compress" the double percents into single ones. – Andriy M Jan 22 '13 at 15:39
  • @AndriyM The one liner is not needed, so I removed it, but your comments are correct. – David Ruhmann Jan 22 '13 at 15:45
  • I like the second solution with the copy instead of xcopy, but it doesn't copy the files. It says that a subdirectory or file already exists and ignores the file copy. I'll play around with it when I have a bit of time to see if I can get it working. – Andrew Jan 22 '13 at 15:50
  • @Andrew For all copy options type `copy /?` in the command line. That issue is occurring because, in batch files the copy command defaults to `/-Y`. Add the `/Y` to the copy command in the batch file. – David Ruhmann Jan 22 '13 at 16:46
  • I took a look at the options and added the `/y` flag for the copy command. It just copies the file structure and not the files. The `echo f !` works like a charm for xcopy, but I get different results when I run the batch, which I don't quite understand. I had it working and half an hour later it reverted to copying everything without making any changes! – Andrew Jan 22 '13 at 17:29
  • @Andrew Update answer. Btw, what are you using to generate the `textfile.txt`? Also are you using any other flags for the `xcopy` command other than `/y`? – David Ruhmann Jan 22 '13 at 18:47
  • The text file is being generated by another script that filters the values and then writes them to a text file (I opened another thread [here](http://stackoverflow.com/questions/14455606/how-do-i-create-a-batch-file-that-reads-a-file-and-writes-a-substring-into-anoth)). I tried the updated script with the `*` and it works a treat! Thank you so much for dedicated your time to this. I hope that other people find your answer useful! – Andrew Jan 22 '13 at 19:07